This commit is contained in:
Javier Valero 2026-11-04 17:02:29 +00:00 • committed by GitHub
commit 86d087dd6d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 40 additions and 1 deletions

View file

@ -21,7 +21,12 @@ Design notes:
* SARIF only has three levels (error / warning / note). Strix's five
severities collapse into them. The raw severity label and CVSS score
survive in ``result.properties.strix`` for downstream tools that can
distinguish CRITICAL vs HIGH.
distinguish CRITICAL vs HIGH; ``properties.strix.severity`` is the only
lossless severity channel in the document.
* Rules link to their reference page through ``helpUri``: the CWE
definition for CWE-keyed rules, the NVD entry for CVE-keyed ones. CWE
rules are also tagged ``external/cwe/cwe-NNN``, the form GitHub
code-scanning recognises as a CWE reference.
* GitHub code-scanning uses ``rule.properties['security-severity']``
(a 0.0-10.0 string) to rank alerts. We populate it from CVSS when
available, otherwise from a conservative label -> score map.
@ -75,6 +80,9 @@ TOOL_INFORMATION_URI = "https://strix.ai"
# findings instead of re-orphaning them on every run.
_SYNTHETIC_LOCATION_URI = "SECURITY.md"
# CVE-keyed rules link to their NVD entry when the id is well formed.
_CVE_ID = re.compile(r"CVE-\d{4}-\d{4,}", re.IGNORECASE)
# SARIF only has three result levels; Strix's five severities collapse here.
# Original label survives in ``result.properties.strix.severity``.
@ -1091,6 +1099,7 @@ def _rule_tags(rule_id: str, report: dict[str, Any]) -> list[str]:
tags: list[str] = ["security"]
if rule_id.startswith("CWE-"):
tags.append(rule_id)
tags.append(f"external/cwe/{rule_id.lower()}")
cve = _string_value(report.get("cve"))
if cve and cve not in tags:
tags.append(cve)
@ -1107,6 +1116,8 @@ def _rule_tags(rule_id: str, report: dict[str, Any]) -> list[str]:
def _help_uri_for(rule_id: str) -> str | None:
if rule_id.startswith("CWE-"):
return f"https://cwe.mitre.org/data/definitions/{rule_id.removeprefix('CWE-')}.html"
if _CVE_ID.fullmatch(rule_id):
return f"https://nvd.nist.gov/vuln/detail/{rule_id.upper()}"
return None

View file

@ -371,3 +371,31 @@ def test_calibration_metadata_survives_into_result_properties(tmp_path: Path) ->
assert strix["confidence_rationale"] == "Reproduced once out of three attempts."
assert strix["severity_change_conditions"] == "Critical if the WAF rule is removed."
assert strix["fix_verification"] == "Not retested."
def _rules(run_dir: Path) -> list[dict[str, Any]]:
rules: list[dict[str, Any]] = _read(run_dir)["runs"][0]["tool"]["driver"]["rules"]
return rules
def test_write_sarif_cwe_rule_links_to_the_cwe_definition(tmp_path: Path) -> None:
write_sarif(tmp_path, [_finding(cwe="CWE-639")])
rule = _rules(tmp_path)[0]
assert rule["id"] == "CWE-639"
assert rule["helpUri"] == "https://cwe.mitre.org/data/definitions/639.html"
# GitHub code scanning reads CWE references from ``external/cwe/cwe-NNN`` tags.
assert "external/cwe/cwe-639" in rule["properties"]["tags"]
assert rule["defaultConfiguration"] == {"level": "error"}
def test_write_sarif_cve_rule_links_to_nvd(tmp_path: Path) -> None:
write_sarif(tmp_path, [_finding(cwe=None, cve="CVE-2021-44228")])
rule = _rules(tmp_path)[0]
assert rule["id"] == "CVE-2021-44228"
assert rule["helpUri"] == "https://nvd.nist.gov/vuln/detail/CVE-2021-44228"
assert not any(tag.startswith("external/cwe/") for tag in rule["properties"]["tags"])
def test_write_sarif_rule_without_a_reference_id_has_no_help_uri(tmp_path: Path) -> None:
write_sarif(tmp_path, [_finding(cwe=None, cve="not-a-cve")])
assert "helpUri" not in _rules(tmp_path)[0]