mirror of
https://github.com/usestrix/strix.git
synced 2026-08-23 19:32:37 +02:00
Refine vulnerability report amendments
This commit is contained in:
@@ -61,6 +61,14 @@ def report_state(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> ReportState
|
||||
endpoint="/redirect",
|
||||
method="GET",
|
||||
cwe="CWE-601",
|
||||
code_locations=[
|
||||
{
|
||||
"file": "src/redirect.py",
|
||||
"start_line": 10,
|
||||
"end_line": 12,
|
||||
"snippet": "return redirect(url)",
|
||||
},
|
||||
],
|
||||
)
|
||||
return state
|
||||
|
||||
@@ -99,20 +107,6 @@ async def test_update_requires_nonempty_reason() -> None:
|
||||
assert result == {"success": False, "error": "update_reason cannot be empty"}
|
||||
|
||||
|
||||
async def test_update_rejects_target_and_cve_changes() -> None:
|
||||
result = await _do_update(
|
||||
report_id="vuln-0001",
|
||||
update_reason="The chain reached a second asset.",
|
||||
target="https://other.example.com",
|
||||
cve="CVE-2024-12345",
|
||||
)
|
||||
|
||||
assert result["success"] is False
|
||||
assert "File a new report instead" in result["error"]
|
||||
assert "target" in result["error"]
|
||||
assert "cve" in result["error"]
|
||||
|
||||
|
||||
async def test_update_changes_impact_only(report_state: ReportState) -> None:
|
||||
result = await _do_update(
|
||||
report_id="vuln-0001",
|
||||
@@ -180,9 +174,6 @@ async def test_update_callback_fires(report_state: ReportState) -> None:
|
||||
|
||||
|
||||
async def test_update_persists_all_report_artifacts(report_state: ReportState) -> None:
|
||||
report_state.final_scan_result = "# Executive Summary\n\nThe scan is complete."
|
||||
report_state.save_run_data()
|
||||
|
||||
result = await _do_update(
|
||||
report_id="vuln-0001",
|
||||
update_reason="The chain proves account takeover.",
|
||||
@@ -194,13 +185,11 @@ async def test_update_persists_all_report_artifacts(report_state: ReportState) -
|
||||
assert result["success"] is True
|
||||
run_dir = report_state.get_run_dir()
|
||||
finding_md = (run_dir / "vulnerabilities" / "vuln-0001.md").read_text(encoding="utf-8")
|
||||
executive_md = (run_dir / "penetration_test_report.md").read_text(encoding="utf-8")
|
||||
findings = json.loads((run_dir / "vulnerabilities.json").read_text(encoding="utf-8"))
|
||||
sarif = json.loads((run_dir / "findings.sarif").read_text(encoding="utf-8"))
|
||||
sarif_finding = sarif["runs"][0]["results"][0]
|
||||
|
||||
assert "An attacker can take over an account." in finding_md
|
||||
assert "An attacker can take over an account." in executive_md
|
||||
assert findings[0]["impact"] == "An attacker can take over an account."
|
||||
assert findings[0]["severity"] == "critical"
|
||||
assert sarif_finding["properties"]["strix"]["impact"] == (
|
||||
@@ -209,6 +198,27 @@ async def test_update_persists_all_report_artifacts(report_state: ReportState) -
|
||||
assert sarif_finding["properties"]["strix"]["severity"] == "critical"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"code_locations",
|
||||
[[], [{"file": "../invalid.py", "start_line": 1}]],
|
||||
)
|
||||
async def test_update_rejects_empty_code_locations(
|
||||
report_state: ReportState,
|
||||
code_locations: list[dict[str, Any]],
|
||||
) -> None:
|
||||
original_locations = report_state.vulnerability_reports[0]["code_locations"]
|
||||
|
||||
result = await _do_update(
|
||||
report_id="vuln-0001",
|
||||
update_reason="The source review did not provide a valid location.",
|
||||
code_locations=code_locations,
|
||||
)
|
||||
|
||||
assert result["success"] is False
|
||||
assert any("code_locations" in error for error in result["errors"])
|
||||
assert report_state.vulnerability_reports[0]["code_locations"] == original_locations
|
||||
|
||||
|
||||
async def test_update_fails_without_global_report_state(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user