Ein SBOM (Software Bill of Materials) listet dir jede Komponente deines Software-Stacks auf und darüber, welche CVEs für diese Komponenten bekannt sind. Was ein SBOM nicht sagt: ob diese CVE in deinem konkreten Deployment überhaupt ausnutzbar ist. Genau diese Lücke schließt VEX: Vulnerability Exploitability eXchange.
Im Artikel zum Vulnerability Management (13.07.) ging es um die generelle Priorisierung von CVEs, Severity, Angriffsfläche, Patch-Aufwand. Dieser Artikel ist spezifischer: Es geht um VEX als Dokumentationsformat und Filtermechanismus, mit dem du aus einer langen CVE-Liste die Einträge herausrechnest, die in deinem Kontext nachweislich nicht greifen.
Das Problem: CVE gelistet heißt nicht CVE ausnutzbar
Scanner wie Grype oder Trivy vergleichen die im SBOM erfassten Paketversionen gegen Schwachstellen-Datenbanken und melden jeden Treffer. Ein Treffer sagt aber nur: „Diese Version dieser Bibliothek hat irgendwo eine bekannte Schwachstelle.“ Ob der verwundbare Codepfad in deinem Build überhaupt aufgerufen wird, ob die Funktion zur Compile-Zeit herausgeschnitten wurde, oder ob eine Mitigation bereits vorgelagert greift, weiß der Scanner nicht. Das Ergebnis: SBOM-Scans produzieren regelmäßig CVE-Listen, in denen ein erheblicher Teil der Treffer im eigenen Kontext irrelevant ist, aber ohne Dokumentation lässt sich das gegenüber Auditoren oder Kunden nicht belegen, sondern nur behaupten.
VEX als Ergänzung zum SBOM
VEX ist keine Alternative zum SBOM, sondern ein zusätzliches Dokument, das pro CVE und Produkt einen Status festhält: betroffen, nicht betroffen, behoben oder in Prüfung. Die Spezifikation OpenVEX definiert dafür genau vier Statuswerte:
affectednot_affectedfixedunder_investigation
Bei not_affected ist eine justification (oder ein impact_statement) Pflicht: eine Begründung, warum die Schwachstelle nicht greift. Laut Spezifikation sind das exakt fünf zulässige Werte:
component_not_presentvulnerable_code_not_presentvulnerable_code_not_in_execute_pathvulnerable_code_cannot_be_controlled_by_adversaryinline_mitigations_already_exist
Ein OpenVEX-Dokument besteht auf oberster Ebene aus @context, @id, author, timestamp, version und einer Liste von statements. Jedes Statement referenziert eine vulnerability, die betroffenen products (als Package-URL) und den status:
{ "@context": "https://openvex.dev/ns/v0.2.0", "@id": "https://example.com/vex/CVE-2014-123456", "author": "Manuel Müller", "role": "Document Creator", "timestamp": "2026-09-18T10:00:00Z", "version": 1, "statements": [ { "vulnerability": { "name": "CVE-2014-123456" }, "products": [ { "@id": "pkg:apk/wolfi/git@2.38.1-r0?arch=x86_64" } ], "status": "not_affected", "justification": "vulnerable_code_not_in_execute_path" } ]}
Ein Statement mit vexctl erzeugen
vexctl baut genau dieses Dokument aus der Kommandozeile. Installation über Homebrew (brew install vexctl) oder aus dem Quellcode (go install github.com/openvex/vexctl@latest, Go 1.21+). Ein not_affected-Statement entsteht so:
vexctl create \ --product="pkg:apk/wolfi/git@2.38.1-r0?arch=x86_64" \ --vuln="CVE-2014-123456" \ --status="not_affected" \ --justification="vulnerable_code_not_in_execute_path"
Das Ergebnis ist ein OpenVEX-JSON-Dokument wie oben, das du versionierst und neben dein SBOM legst.
Scanner-Ergebnisse filtern: vexctl filter
Der eigentliche Nutzen zeigt sich beim Filtern. vexctl filter nimmt laut README aktuell SARIF-formatierte Scan-Ergebnisse entgegen und rechnet die im VEX-Dokument als not_affected markierten Treffer heraus:
vexctl filter scan_results.sarif.json vex_data.csaf
Grype und Trivy scannen nicht nativ im VEX-Format, liefern aber beide SARIF als Ausgabeoption: Grype mit --output sarif, Trivy mit --format sarif (jeweils per -o/-o file speicherbar). Der Workflow sieht damit so aus:
grype dein-image:tag --output sarif --file scan_results.sarif.jsonvexctl filter scan_results.sarif.json vex_data.csaf
Wichtig für den Praxiseinsatz: Laut vexctl-README ist die SARIF-Unterstützung der aktuell dokumentierte Weg, proprietäre Scanner-Formate werden als zukünftige Erweiterung genannt, sind aber zum Zeitpunkt dieses Artikels nicht Teil der README-Dokumentation. Prüfe vor dem produktiven Einsatz die aktuelle vexctl-Version gegen die dort beschriebenen Flags.
Fazit
VEX ersetzt keine Priorisierung, es macht sie belegbar. Ein SBOM sagt dir, was drinsteckt. Ein VEX-Dokument sagt dir, was davon du geprüft hast und warum ein Treffer als nicht ausnutzbar gilt: nachvollziehbar für jeden, der nachfragt, nicht nur für dich selbst.
Hinterlasse einen Kommentar