diff --git a/.opencode/agents/reporter.md b/.opencode/agents/reporter.md index 0527e506..c6209d98 100644 --- a/.opencode/agents/reporter.md +++ b/.opencode/agents/reporter.md @@ -24,6 +24,7 @@ Before writing a report, read: - relevant files under `itemdb/notes/` - findings under `itemdb/findings/` (including `EXPLOITED/`, `CONFIRMED/`, `PENDING/`, `REJECTED/`, `DUPLICATE/`) - evidence under `itemdb/evidence/` (including `exploits/` subdirectories) +- If present, `itemdb/notes/threat-model.md` — use to provide attacker-model context, trust-boundary descriptions, and scope grounding in Methodology, Scope, and Limitations sections. Use target-specific skills only when useful for explaining target context. @@ -137,6 +138,8 @@ Describe the CodeCome workflow used: Mention whether validation was static, runtime, sandboxed, benchmark-based, HTTP-based, CLI-based, sanitizer-based, etc. +When `itemdb/notes/threat-model.md` is available, briefly summarize the attacker model (capabilities and explicit non-capabilities) and threat assumptions that scoped the review. Do not reproduce the entire threat model. + ## Scope Describe what was in scope. @@ -148,6 +151,8 @@ Include: - excluded directories, - whether tests, examples, generated code, vendor code, or benchmark labels were considered. +When the threat model is available, reference documented trust boundaries, in-scope assets, and security objectives. + ## Findings summary Include a summary table: @@ -257,6 +262,8 @@ Examples: - out-of-scope directories, - no production environment tested. +When the threat model is available, include open assumptions from `itemdb/notes/threat-model.md` that may affect severity or exploitability. + ## Recommended next steps Give actionable next steps. diff --git a/.opencode/skills/report-writing/SKILL.md b/.opencode/skills/report-writing/SKILL.md index f78a5b6c..e70cf852 100644 --- a/.opencode/skills/report-writing/SKILL.md +++ b/.opencode/skills/report-writing/SKILL.md @@ -34,6 +34,7 @@ Read: - `itemdb/findings/REJECTED/` - `itemdb/findings/DUPLICATE/` - `itemdb/evidence/` +- If present, `itemdb/notes/threat-model.md` — operational threat model with attacker capabilities, non-capabilities, trust boundaries, existing controls, assets, and open assumptions. Use to ground Methodology, Scope, and Limitations sections without duplicating the full artifact. ## Outputs diff --git a/prompts/phase-6-report.md b/prompts/phase-6-report.md index f90701a1..92b9b164 100644 --- a/prompts/phase-6-report.md +++ b/prompts/phase-6-report.md @@ -16,6 +16,7 @@ Read the following files (all paths are relative to the project/workspace root): - all relevant files under `itemdb/notes/` - all findings under `itemdb/findings/` - all relevant evidence under `itemdb/evidence/` +- If present, `itemdb/notes/threat-model.md` — operational threat model from Phase 1b: attacker capabilities and non-capabilities, trust-boundary summary, assets and security objectives, existing controls, and open assumptions. Use to ground Methodology, Scope, and Limitations sections. ## Goal @@ -88,6 +89,11 @@ Use this structure: - Include limitations. - Include actionable next steps. - Use concise, reviewable Markdown. +- When `itemdb/notes/threat-model.md` is available, use it to ground report + context: summarize the attacker model in Methodology, reference trust + boundaries and assets in Scope, and note open assumptions in Limitations. + Do NOT use abuse-path themes or speculative threat-model content to inflate + severity or imply impact beyond what confirmed findings and evidence support. ## Finding summary table @@ -199,7 +205,9 @@ Examples: - findings generated by AI and requiring human review, - out-of-scope directories, - no production environment tested, -- exploit demonstrations limited to sandbox environment. +- exploit demonstrations limited to sandbox environment, +- threat-model assumptions that may affect severity or exploitability (when + `itemdb/notes/threat-model.md` is present). ## Final response diff --git a/templates/report.md b/templates/report.md index c968509d..5e6c58a4 100644 --- a/templates/report.md +++ b/templates/report.md @@ -56,6 +56,12 @@ Mention whether validation was: - sanitizer-based, - test-based. +When a project threat model exists (`itemdb/notes/threat-model.md`), summarize: + +- attacker model assumed (capabilities and explicit non-capabilities), +- threat assumptions that scoped the review, +- key trust boundaries considered. + # Scope Describe what was in scope. @@ -68,6 +74,12 @@ Include: - target-specific assumptions, - whether tests/examples/generated code/vendor code were included. +When the threat model is available, include: + +- documented trust boundaries, +- assets and security objectives in scope, +- attacker postures considered. + # Findings summary | ID | Status | Severity | Confidence | CWE | Target area | Title | Evidence | Recording | @@ -209,6 +221,7 @@ Examples: - Production systems were not tested. - Some target components may not have been built or executed. - Some dependencies, credentials, or fixtures may be missing. +- Threat-model assumptions that may affect severity or exploitability (only when `itemdb/notes/threat-model.md` is present). # Recommended next steps diff --git a/tests/test_prompts_threat_model.py b/tests/test_prompts_threat_model.py index 333d7b25..8464575c 100644 --- a/tests/test_prompts_threat_model.py +++ b/tests/test_prompts_threat_model.py @@ -282,3 +282,101 @@ def test_exploit_readme_template_mentions_non_capabilities() -> None: def test_exploit_readme_template_mentions_open_assumptions() -> None: content = _read_opencode("templates/exploit-readme.md") assert "open assumptions" in content.lower() + + +# --------------------------------------------------------------------------- +# Phase 6 reporter agent — threat-model.md integration +# --------------------------------------------------------------------------- + +def test_reporter_agent_references_threat_model() -> None: + content = _read_opencode(".opencode/agents/reporter.md") + assert "itemdb/notes/threat-model.md" in content + + +def test_reporter_agent_uses_conditional_language() -> None: + content = _read_opencode(".opencode/agents/reporter.md") + content_lower = content.lower() + assert ( + "when available" in content_lower + or "when present" in content_lower + or "if present" in content_lower + ) + + +def test_reporter_agent_mentions_attacker_model() -> None: + content = _read_opencode(".opencode/agents/reporter.md") + assert "attacker model" in content.lower() or "attacker-model" in content.lower() + + +def test_reporter_agent_mentions_threat_model_in_limitations() -> None: + content = _read_opencode(".opencode/agents/reporter.md") + assert "threat model" in content.lower() or "threat-model" in content.lower() + assert "open assumptions" in content.lower() + + +# --------------------------------------------------------------------------- +# Phase 6 report-writing skill — threat-model.md integration +# --------------------------------------------------------------------------- + +def test_report_writing_skill_references_threat_model() -> None: + content = _read_opencode(".opencode/skills/report-writing/SKILL.md") + assert "itemdb/notes/threat-model.md" in content + + +def test_report_writing_skill_mentions_attacker() -> None: + content = _read_opencode(".opencode/skills/report-writing/SKILL.md") + assert "attacker" in content.lower() + + +# --------------------------------------------------------------------------- +# Phase 6 prompt — threat-model.md integration +# --------------------------------------------------------------------------- + +def test_phase_6_explicitly_references_threat_model_when_present() -> None: + content = _read_prompt("phase-6-report.md") + assert "itemdb/notes/threat-model.md" in content + + +def test_phase_6_uses_conditional_language() -> None: + content = _read_prompt("phase-6-report.md") + content_lower = content.lower() + assert ( + "when available" in content_lower + or "when present" in content_lower + or "if present" in content_lower + ) + + +def test_phase_6_mentions_trust_boundaries() -> None: + content = _read_prompt("phase-6-report.md") + assert "trust boundar" in content.lower() or "trust-boundary" in content.lower() + + +def test_phase_6_mentions_attacker_model_in_methodology() -> None: + content = _read_prompt("phase-6-report.md") + assert "attacker model" in content.lower() or "attacker-model" in content.lower() + + +def test_phase_6_guards_against_speculative_severity() -> None: + content = _read_prompt("phase-6-report.md") + content_lower = content.lower() + assert "inflate" in content_lower or "abuse-path" in content_lower + + +# --------------------------------------------------------------------------- +# Report template — threat-model context +# --------------------------------------------------------------------------- + +def test_report_template_mentions_threat_model() -> None: + content = _read_opencode("templates/report.md") + assert "threat model" in content.lower() or "threat-model" in content.lower() + + +def test_report_template_mentions_trust_boundaries_in_scope() -> None: + content = _read_opencode("templates/report.md") + assert "trust boundar" in content.lower() + + +def test_report_template_mentions_attacker_model_in_methodology() -> None: + content = _read_opencode("templates/report.md") + assert "attacker model" in content.lower()