fix(app-scan): pair Blender's "Blender Foundation" spelling on cvelistV5
Field case: Blender 5.0.0 (Intune) and 5.0.1 (Wazuh) got CVE-2026-60103 but none of CVE-2026-119718..119722, published 2026-10-30. The same CNA (VulnCheck) wrote the new records as vendor "Blender Foundation" / product "Blender", while CVE-2026-60103 says "blender" / "blender". Only the latter was paired, so the five records passed the byte prefilter and were dropped at pairing. A fresher nightly index would not have changed that. NVD has CVE-2026-119722 "Awaiting Analysis" with no configuration, so cvelistV5 is still the only structured source. Each record states two lines, "0" .. lessThan "4.5.15" and "5.0.0" .. lessThan "5.2.3"; they are matched per line, so 5.0.x is shown the 5.2.3 fix and the 4.5 LTS line the 4.5.15 one. All five IDs go through the real index build in the test. Index key bumped to v56.
This commit is contained in:
+9
-6
@@ -1856,13 +1856,16 @@ install.
|
||||
"Deferred" with no configuration as of 2026-10-13, and its `blender:blender`
|
||||
rows stop at 2022. The record states `3.0.0 .. lessThanOrEqual "5.1.2"` (fix
|
||||
shown as `>5.1.2`) plus an `unaffected` git commit, which is not a version and
|
||||
is ignored. Only the vendor's spelling `blender / blender` is paired; the 2022
|
||||
records name the vendor "n/a" and write prose ("Blender versions prior to
|
||||
2.83.19, 2.93.8 and 3.1"). Names are anchored ("Blender", "Blender 4.2 LTS"),
|
||||
so launchers and add-ons stay out. Windows and macOS hosts only: a distro
|
||||
is ignored. CVE-2026-119718..119722 (published 2026-10-30, NVD "Awaiting
|
||||
Analysis") come from the same CNA (VulnCheck) as `Blender Foundation / Blender`
|
||||
with two lines, `0 .. <4.5.15` and `5.0.0 .. <5.2.3`; both spellings are
|
||||
paired, and a 4.5 LTS host is shown the 4.5.15 fix. "n/a" stays out: the 2022
|
||||
records there write prose ("Blender versions prior to 2.83.19, 2.93.8 and
|
||||
3.1"). Names are anchored ("Blender", "Blender 4.2 LTS"), so launchers and
|
||||
add-ons stay out. Windows and macOS hosts only: a distro
|
||||
package ("4.3.2+dfsg-2") cleans to 4.3.2 and says nothing about backports.
|
||||
Known limit: the range covers the 4.5 LTS line, and a fix backported there
|
||||
closes the finding only once the record names it.
|
||||
Known limit: CVE-2026-60103's range covers the 4.5 LTS line, and a fix
|
||||
backported there closes the finding only once the record names it.
|
||||
|
||||
**GnuPG** (`gnupg:gnupg` on NVD, no cvelistV5 row). The inventory names GnuPG's
|
||||
own Windows installer "GNU Privacy Guard". NVD bounds each branch
|
||||
|
||||
@@ -44,7 +44,7 @@ _ZIP_PATH = "/tmp/truevuln-cvelistv5-cache.zip"
|
||||
_ZIP_URL = "https://github.com/CVEProject/cvelistV5/archive/refs/heads/main.zip"
|
||||
_ZIP_TTL = 12 * 3600
|
||||
_ZIP_MIN_BYTES = 100_000_000 # sanity floor; the real ZIP is ~557 MB
|
||||
_INDEX_SETTING = "cvelistv5_product_index_v55" # v55: Cisco Webex
|
||||
_INDEX_SETTING = "cvelistv5_product_index_v56" # v56: Blender Foundation
|
||||
_INDEX_TTL = timedelta(hours=26) # rebuilt nightly; a missed night still serves
|
||||
|
||||
# Curated registry: name-regex (installed software) → cvelistV5 (vendor,
|
||||
@@ -463,10 +463,12 @@ _REGISTRY: List[dict] = [
|
||||
"pairs": [("lenovo", "system update")]},
|
||||
# Blender. NVD left CVE-2026-60103 "Deferred" with no configuration and its
|
||||
# blender:blender rows stop at 2022, so this is the only structured source
|
||||
# ("3.0.0" .. lessThanOrEqual "5.1.2"). Vendor's own spelling only: the
|
||||
# 2022 records under "n/a" write prose into the version field.
|
||||
# ("3.0.0" .. lessThanOrEqual "5.1.2"). The same CNA (VulnCheck) wrote
|
||||
# CVE-2026-119718..119722 as "Blender Foundation" (0 .. <4.5.15, 5.0.0 ..
|
||||
# <5.2.3), so both spellings. Not "n/a": the 2022 records there write
|
||||
# prose into the version field.
|
||||
{"key": "blender", "re": r"^blender(?: \d+(?:\.\d+)*(?: lts)?)?$",
|
||||
"pairs": [("blender", "blender")]},
|
||||
"pairs": [("blender", "blender"), ("blender foundation", "blender")]},
|
||||
# Ghostscript. NVD had no configuration for CVE-2026-39919 ("0" .. lessThan
|
||||
# "10.08.0"). Artifex's own spellings only: the 2019-2020 Red Hat records
|
||||
# ("n/a", "The ghostscript Project", ...) write prose or the FIXED version
|
||||
|
||||
+34
-12
@@ -32,6 +32,16 @@ B_60103 = {"defaultStatus": "affected", "vendor": "blender", "product": "blender
|
||||
"lessThanOrEqual": "5.1.2"},
|
||||
{"status": "unaffected", "version": "968972a918b5ed2d534295b639c54449d7de11cd",
|
||||
"versionType": "git"}]}
|
||||
# CVE-2026-119718..119722 (published 2026-10-30): another CNA, vendor spelled
|
||||
# "Blender Foundation", two lines: everything before the 4.5 LTS fix, and 5.x
|
||||
# before 5.2.3. All five carry this same block.
|
||||
NEW = [f"CVE-2026-1197{n}" for n in (18, 19, 20, 21, 22)]
|
||||
B_119722 = {"vendor": "Blender Foundation", "product": "Blender", "defaultStatus": "unaffected",
|
||||
"repo": "https://projects.blender.org/blender/blender",
|
||||
"versions": [{"version": "0", "lessThan": "4.5.15", "status": "affected",
|
||||
"versionType": "semver"},
|
||||
{"version": "5.0.0", "lessThan": "5.2.3", "status": "affected",
|
||||
"versionType": "semver"}]}
|
||||
# CVE-2017-2899: one exact release.
|
||||
B_2899 = {"vendor": "Blender", "product": "Blender",
|
||||
"versions": [{"status": "affected", "version": "v2.78c"}]}
|
||||
@@ -54,7 +64,7 @@ def _build_index():
|
||||
os.close(fd)
|
||||
with zipfile.ZipFile(path, "w") as zf:
|
||||
for cve_id, aff in (("CVE-2026-60103", B_60103), ("CVE-2017-2899", B_2899),
|
||||
("CVE-2022-0544", B_0544)):
|
||||
("CVE-2022-0544", B_0544), *((c, B_119722) for c in NEW)):
|
||||
year, num = cve_id.split("-")[1:]
|
||||
zf.writestr(f"cvelistV5-main/cves/{year}/{num[:-3]}xxx/{cve_id}.json",
|
||||
json.dumps({"cveMetadata": {"cveId": cve_id},
|
||||
@@ -98,27 +108,39 @@ def demo():
|
||||
assert c5.resolve(other) is None, other
|
||||
assert c5._pair_key("blender", "blender") == "blender"
|
||||
assert c5._pair_key("Blender", "Blender") == "blender"
|
||||
assert c5._pair_key("Blender Foundation", "Blender") == "blender"
|
||||
assert c5._pair_key("n/a", "Blender") is None
|
||||
|
||||
# --- end to end: index build → scan --------------------------------------
|
||||
index = _build_index()
|
||||
assert sorted(e["cve"] for e in index["blender"]) == ["CVE-2017-2899", "CVE-2026-60103"]
|
||||
# The reference hosts: Intune 5.0.0, Wazuh 5.0.1. No patched build is named.
|
||||
assert _scan(index, "Blender", "5.0.0") == [("CVE-2026-60103", ">5.1.2")]
|
||||
assert _scan(index, "Blender", "5.0.1") == [("CVE-2026-60103", ">5.1.2")]
|
||||
assert _scan(index, "Blender", "5.1.2") == [("CVE-2026-60103", ">5.1.2")]
|
||||
assert _scan(index, "Blender", "3.0.0") == [("CVE-2026-60103", ">5.1.2")]
|
||||
# Above the bound, and below the 3.0.0 floor: nothing.
|
||||
assert _scan(index, "Blender", "5.1.3") == []
|
||||
assert _scan(index, "Blender", "2.93.18") == []
|
||||
assert sorted({e["cve"] for e in index["blender"]}) == sorted(
|
||||
["CVE-2017-2899", "CVE-2026-60103", *NEW])
|
||||
|
||||
def new(fix):
|
||||
return [(c, fix) for c in NEW]
|
||||
on_5x = sorted(new("5.2.3") + [("CVE-2026-60103", ">5.1.2")])
|
||||
on_lts = sorted(new("4.5.15") + [("CVE-2026-60103", ">5.1.2")])
|
||||
# The reference hosts: Intune 5.0.0, Wazuh 5.0.1.
|
||||
assert _scan(index, "Blender", "5.0.0") == on_5x
|
||||
assert _scan(index, "Blender", "5.0.1") == on_5x
|
||||
assert _scan(index, "Blender", "5.1.2") == on_5x
|
||||
# Between the two bounds: only the 5.x line of the new records.
|
||||
assert _scan(index, "Blender", "5.1.3") == new("5.2.3")
|
||||
assert _scan(index, "Blender", "5.2.2") == new("5.2.3")
|
||||
assert _scan(index, "Blender", "5.2.3") == []
|
||||
# The 4.5 LTS line: fixed in 4.5.15, so the fix shown is that one, not 5.2.3.
|
||||
assert _scan(index, "Blender", "4.5.14") == on_lts
|
||||
assert _scan(index, "Blender", "4.5.15") == [("CVE-2026-60103", ">5.1.2")]
|
||||
assert _scan(index, "Blender", "3.0.0") == on_lts
|
||||
assert _scan(index, "Blender", "2.93.18") == new("4.5.15")
|
||||
# macOS lists the app as plain "Blender" too.
|
||||
assert _scan(index, "Blender", "5.0.1", "macOS 15.5") == [("CVE-2026-60103", ">5.1.2")]
|
||||
assert _scan(index, "Blender", "5.0.1", "macOS 15.5") == on_5x
|
||||
# A distro package: "+dfsg-2" is trimmed to 4.3.2, which says nothing about
|
||||
# backports. Linux is Wazuh's.
|
||||
for os_name in ("Debian GNU/Linux 13", "Ubuntu 24.04.3 LTS", "Linux"):
|
||||
assert _scan(index, "blender", "4.3.2+dfsg-2", os_name) == [], os_name
|
||||
|
||||
print("ok blender resolves, 5.0.0 and 5.0.1 get CVE-2026-60103, 5.1.3 and 2.93 do not")
|
||||
print("ok blender resolves under both vendor spellings, both ranges of CVE-2026-119718..119722 hold")
|
||||
|
||||
|
||||
def test_blender():
|
||||
|
||||
Reference in New Issue
Block a user