Files
vulncheck/tests/test_adobe_matching.py
T
vulncheckandClaude Opus 5 f64902417e feat(scan): detect the Adobe Creative Cloud desktop apps
Illustrator, Photoshop, InDesign and Bridge were blind spots — nothing looked
at them at all, on software that ships dozens of code-execution CVEs per
patch day (APSB26-42, -51, -40, -32, -39, -89).

Both sources carry them well, so both paths are wired up. cvelistV5 names two
of the four with a "Desktop" suffix ("Photoshop Desktop", "InDesign Desktop")
and two without ("Illustrator", "Bridge"), which is not a pattern — each name
is listed. Verified against CVE-2026-34661, -27289, -27283 and -34630.

The inventory names carry a YEAR the CVE records never mention ("Adobe
Illustrator 2026" at version 30.1), so the year is ignored rather than parsed
— the version field is what gets compared. Two InDesign generations can sit on
one host and both resolve to the same product, each judged on its own version.

Anchored, and the helper components that ship alongside are excluded:
AdobeNotificationClient, Adobe Refresh Manager and AdobeAcrobatDCCoreApp are
not the products and carry unrelated version numbers — the same trap the
dictionary pack sprang last commit.

Index key bumped to v16.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 10:06:50 +02:00

91 lines
3.5 KiB
Python

"""Adobe product vs add-on — run: python tests/test_adobe_matching.py
Adobe's own name appears inside the names of its add-ons, and those add-ons
carry version numbers that look exactly like old Reader builds — the dictionary
pack ships as 23.008.20421. An unanchored match therefore reported every Reader
CVE against them (tester: CVE-2026-48373 listed eight times on one host, none
of them the Reader itself).
"""
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 resolve_product
from app.services import cvelistv5_scan_service as c5
PRODUCTS = [
"Adobe Acrobat Reader DC - Deutsch",
"Adobe Acrobat Reader (64-bit)",
"Adobe Acrobat (64-bit)",
"Acrobat Reader DC",
]
ADDONS = [
"Asian Language And Spelling Dictionaries Support For Adobe Acrobat Reader",
"Adobe Acrobat Reader DC Language Pack",
"Adobe Acrobat Font Pack",
"Spelling Dictionaries Support For Adobe Reader",
]
def demo():
for n in PRODUCTS:
assert resolve_product(n), n # NVD-CPE path
assert c5.resolve(n) == "adobe-acrobat", n # cvelistV5 path
for n in ADDONS:
assert resolve_product(n) is None, n
assert c5.resolve(n) is None, n
# Reader and Acrobat stay on their own CPE names.
assert resolve_product("Adobe Acrobat Reader (64-bit)")["key"] \
== "cpe:adobe:acrobat_reader_dc"
assert resolve_product("Adobe Acrobat (64-bit)")["key"] == "cpe:adobe:acrobat_dc"
# Both query the alternate spelling NVD kept alive alongside.
assert resolve_product("Adobe Acrobat Reader (64-bit)")["also"] \
== ["cpe:2.3:a:adobe:acrobat_reader"]
print("adobe matching OK")
def demo_creative_cloud():
"""The Creative-Cloud desktop apps, added after the Acrobat work.
Their inventory names carry a YEAR ("Adobe Illustrator 2026") that no CVE
record ever mentions — the version compared is the version field (30.1).
Two InDesign generations can sit on one host, and both must resolve.
cvelistV5 names two of the four with a "Desktop" suffix and two without,
so the names are listed rather than patterned.
"""
apps = {
"Adobe Illustrator 2026": ("cpe:adobe:illustrator", "adobe-illustrator"),
"Adobe Photoshop 2026": ("cpe:adobe:photoshop", "adobe-photoshop"),
"Adobe InDesign 2025": ("cpe:adobe:indesign", "adobe-indesign"),
"Adobe InDesign 2026": ("cpe:adobe:indesign", "adobe-indesign"),
"Adobe Bridge 2026": ("cpe:adobe:bridge", "adobe-bridge"),
}
for name, (cpe_key, c5_key) in apps.items():
assert resolve_product(name)["key"] == cpe_key, name
assert c5.resolve(name) == c5_key, name
# Helper components ship alongside and are NOT the products.
for helper in ("AdobeNotificationClient", "Adobe Refresh Manager",
"AdobeAcrobatDCCoreApp", "Adobe Creative Cloud"):
assert resolve_product(helper) is None, helper
assert c5.resolve(helper) is None, helper
# The vendor/product spellings the records actually use.
for v, p, key in (("Adobe", "Illustrator", "adobe-illustrator"),
("Adobe", "Photoshop Desktop", "adobe-photoshop"),
("Adobe", "InDesign Desktop", "adobe-indesign"),
("Adobe", "Bridge", "adobe-bridge")):
assert c5._pair_key(v, p) == key, (v, p)
print("adobe creative cloud OK")
if __name__ == "__main__":
demo()
demo_creative_cloud()