Reject CVE ids that are a truncation of the one a repo is about

A README caption in maniakh/CVE-2026-31431---Copy-Fail-PoC reads
"Copy Fail (CVE-2026-3143)", one digit short. That still parses as a
valid identifier, and the guard meant to catch it was satisfied by the
repo's generic exploit.py, so the PoC was filed against an unrelated
WordPress advisory. CVE-2026-8222 (Open5GS) collected a GiveWP lab the
same way. Drop an id from the same year that a longer mentioned id
extends, unless the repository name deliberately carries both.

Underscores are word characters, so the id regex matched neither half of
a name like CVE-2022-4174_CVE-2022-41742; read the separator-normalised
name too. Over 600 live candidates that recovers two real PoCs the gap
was hiding, Keycloak_CVE-2026-18963_PoC and CVE-2026-42945_NginxRift.
This commit is contained in:
0xMarcio committed 2026-08-30 17:38:58 +02:00
1 parent 56a945f9bb
commit 0aa40a5f49
1 file changed
+25 -1
+25 -1
View File
@@ -244,6 +244,20 @@ def root_has_code(repo: dict[str, Any]) -> bool:
return any(CODE_FILE_RE.search(name) for name in root_entry_names(repo))
def truncated_ids(cve_ids: Collection[str]) -> set[str]:
"""Identifiers that a longer identifier from the same year extends."""
numbers: dict[str, set[str]] = defaultdict(set)
for cve_id in cve_ids:
_, year, number = cve_id.split("-")
numbers[year].add(number)
return {
f"CVE-{year}-{number}"
for year, values in numbers.items()
for number in values
if any(other.startswith(number) for other in values - {number})
}
def readme_has_poc_context(readme: str, cve_id: str, full_name: str = "") -> bool:
year, number = cve_id.split("-")[1:]
pattern = re.compile(rf"\bCVE[-_ ]{re.escape(year)}[-_ ]{re.escape(number)}\b", re.IGNORECASE)
@@ -282,10 +296,20 @@ def qualifying_repo_cves(
description = str(repo.get("description") or "")
topics = " ".join(topic_names(repo))
readme = readme_text(repo)
name_cves = extract_cves(full_name, year)
# Underscores are word characters, so a raw name like CVE-A_CVE-B matches
# neither identifier; read the separator-normalised form as well.
name_cves = extract_cves(full_name, year) | extract_cves(normalise_identity(full_name), year)
description_cves = extract_cves(description, year)
topic_cves = extract_cves(topics, year)
readme_cves = extract_cves(readme, year)
# A caption or description that drops a digit — "CVE-2023-3883" written for
# CVE-2023-38831 — still parses as a valid identifier and would otherwise
# enrol the repository against whatever unrelated advisory owns it. Trust
# the repository name, which may deliberately carry both identifiers.
truncated = truncated_ids(name_cves | description_cves | topic_cves | readme_cves) - name_cves
description_cves -= truncated
topic_cves -= truncated
readme_cves -= truncated
identity_cves = name_cves | description_cves | topic_cves
identity_text = normalise_identity(f"{full_name} {description}")
identity_has_poc = bool(POC_RE.search(identity_text))