Files
vulncheck/tests/test_checkmk_version.py
T
vulncheckandClaude Opus 5 793e840665 feat(scan): index CVEs that name a single exact version
A record stating one affected version and no bound at all was dropped
entirely, so the CVE never entered the index and nothing but Defender could
report it. CVE-2026-14266 is exactly that shape: "7-Zip 20.01, status
affected", nothing else.

They were dropped to avoid over-matching, which is a real risk — an unbounded
floor swallows every version above it. A single exact version has no such
problem when it is read as the closed range [v, v]: it matches that one
version and nothing else, which is precisely what the record claims. 20.01
hits, 20.01.0 hits (same version, written differently), 19.00 and 26.01 do
not.

Index key bumped to v12; the cached index has none of these entries.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 13:52:09 +02:00

58 lines
2.5 KiB
Python

"""Checkmk inline patch versions — run: python tests/test_checkmk_version.py
Checkmk numbers patches inside the version string (2.4.0p12), and both NVD
and cvelistV5 state their bounds the same way (lessThan "2.4.0p13"). The
dotted-numeric rule discarded the whole version, so the agent was invisible
to every scan path — Wazuh does not detect it either (wazuh/wazuh#35646).
"""
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from app.services.app_cve_scanner_service import _clean_version, _vcmp
from app.services.cvelistv5_scan_service import _affected
def demo():
assert _clean_version("2.4.0p12") == "2.4.0p12"
assert _clean_version("2.4.0") == "2.4.0"
# Linux distro versions stay excluded — that rule is why this was strict.
assert _clean_version("1:3.2") is None
assert _clean_version("4.6.5-3.el8") is None
assert _clean_version("2.43.0.windows.1") is None
assert _vcmp("2.4.0p12", "2.4.0p13") < 0
assert _vcmp("2.4.0p13", "2.4.0p13") == 0
assert _vcmp("2.4.0p12", "2.3.0p38") > 0 # newer branch, lower patch no.
# CVE-2025-32919's three branch bounds, verbatim.
branches = [("2.4.0", "2.4.0p13"), ("2.3.0", "2.3.0p38"), ("2.2.0", "2.2.0p46")]
# The tester's agent: 2.4.0p12 — affected, and only by its own branch.
assert [_affected("2.4.0p12", s, lt, None) for s, lt in branches] == \
[True, False, False]
# Patched on that branch.
assert not any(_affected("2.4.0p13", s, lt, None) for s, lt in branches)
# An older branch answers for itself, not for the newer ones.
assert [_affected("2.3.0p10", s, lt, None) for s, lt in branches] == \
[False, True, False]
# A record that names ONE exact version and no bound at all — dropping
# these hid the CVE completely (CVE-2026-14266: "7-Zip 20.01 affected"),
# so only Defender reported it. Read as the closed range [v, v].
from app.services.cvelistv5_scan_service import _ranges_from_affected
exact = _ranges_from_affected(
{"vendor": "7-Zip", "product": "7-Zip", "defaultStatus": "unknown",
"versions": [{"version": "20.01", "status": "affected"}]})
assert exact == [("20.01", None, "20.01")], exact
hit = lambda v: any(_affected(v, s, lt, lte) for s, lt, lte in exact)
assert hit("20.01") and hit("20.01.0") # same version, written two ways
assert not hit("26.01") and not hit("19.00")
print("checkmk version OK")
if __name__ == "__main__":
demo()