Files
vulncheck/tests/test_eol_supersede.py
T
vulncheck 544d6c6eec fix(eol): only the product itself may claim its release year
Office, SharePoint and Exchange take their release from the year in the
inventory NAME, so every companion package that happens to carry a year
claimed that release was installed: "Microsoft Office 2007 Primary Interop
Assemblies", "Microsoft Exchange Server 2010 MAPI Client and CDO",
"Microsoft SharePoint 2013 Client Components SDK". Each produced a CRITICAL
EOL finding for a product the host does not run — the tester's Exchange SE
host, fully supported, carried an EOL-MSEXCHANGE-2007.

Naming the add-ons one at a time is a race nobody wins; there is always
another rollup. What separates the product from its companions is what
FOLLOWS the year: the product name ends there, or continues with an edition
or update qualifier ("2016 Cumulative Update 23", "Professional Plus 2016 -
de-de"). Any other word after the year belongs to a different product that
merely names this one. Both resolvers consult the same rule, so a companion
is refused whichever source would have matched it.

Second half of the same report: the status loop. These slugs are
single-release, so each companion superseded the others' finding once per
sweep — 2007 closes 2016, 2016 reopens and closes 2007, every run, with
nothing changing on the host. Supersede now leaves alone any finding the
same sweep already confirmed: the sweep saw both products in one inventory,
so neither replaced the other. Dropping the companions removes the cause;
this removes the mechanism.

The real entries are untouched — "Microsoft Exchange Server 2016 Cumulative
Update 23" and the plain "Microsoft Exchange Server" both still resolve to
release 2016 (EOL 2025-10-14), so the host's genuine finding stands.
2026-08-13 11:42:38 +02:00

80 lines
3.0 KiB
Python

"""EOL supersede must not fire on side-by-side products.
The tester's host has Visual C++ 2008, 2010, 2012, 2013, 2015 and 2022
redistributables installed at once — normal on Windows, and several of them
genuinely EOL. Supersede assumed one release per product, so within a single
scan the 2008 entry closed the 2013 finding as "superseded", the 2013 entry
reopened it and closed 2008, and so on: 50 alternating change-history rows and
hundreds of audit entries a night, with nothing on the host changing.
"""
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from app.services.eol_service import ( # noqa: E402
_SINGLE_RELEASE_SLUGS, _pseudo_cve_id, _supersede_old_eol,
resolve_product_slug)
from app.models.vulnerability import VulnerabilityStatus # noqa: E402
class _Vuln:
def __init__(self, vid, cve_id):
self.id, self.cve_id = vid, cve_id
self.status = VulnerabilityStatus.open
self.patched_at = None
class _Query:
def __init__(self, rows): self.rows = rows
def filter(self, *a, **k): return self
def all(self): return self.rows
class _DB:
def __init__(self, rows): self.rows = rows
def query(self, *a, **k): return _Query(self.rows)
def protect_check():
"""A finding this same sweep confirmed must never be superseded — that
mutual close/reopen is the open→patched→open loop."""
other = _Vuln(7, "EOL-MSEXCHANGE-2019")
db = _DB([other])
_supersede_old_eol(db, 1, "msexchange", "EOL-MSEXCHANGE-2016",
protect_ids={7})
assert other.status == VulnerabilityStatus.open
# Unprotected (not seen this run) → still closed, as before.
_supersede_old_eol(db, 1, "msexchange", "EOL-MSEXCHANGE-2016")
assert other.status == VulnerabilityStatus.patched
def demo():
protect_check()
# Side by side → never superseded.
for name in ("Microsoft Visual C++ 2013 Redistributable (x86) - 12.0.21005",
"Microsoft Visual C++ 2008 Redistributable - x64 9.0.30729"):
assert resolve_product_slug(name) not in _SINGLE_RELEASE_SLUGS, name
for slug in ("mssqlserver", "oracle-jdk", "dotnetfx", "nodejs", "python"):
assert slug not in _SINGLE_RELEASE_SLUGS, slug
# One per device → supersede is what keeps the old release from lingering.
for slug in ("chrome", "firefox", "windows", "windows-server", "msexchange"):
assert slug in _SINGLE_RELEASE_SLUGS, slug
assert resolve_product_slug("Google Chrome") in _SINGLE_RELEASE_SLUGS
# The reported case: the two ids are distinct, so the old code saw each as
# the other's stale duplicate.
a = _pseudo_cve_id("ms-lifecycle", "Visual C++ 2013 Redistributable")
b = _pseudo_cve_id("ms-lifecycle", "Visual C++ 2008 Redistributable")
assert a != b
assert "ms-lifecycle" not in _SINGLE_RELEASE_SLUGS, (
"the Microsoft lifecycle export covers many co-installed products")
print("ok supersede fires only where a device runs one release")
if __name__ == "__main__":
demo()