The Problem: Alert Fatigue and False Positives
Every day, your vulnerability scanner finds dozens of security alerts that demand review. Your team dutifully reviews each one and discovers that 85% of them do not actually affect your application. Why is this happening? The vulnerability may require a specific configuration your application does not use, your application may not be able to reach the vulnerable code path even though the component is present, you may have mitigated the risk in a way the scanner does not understand, the vulnerability may have already been patched in your build, or the vulnerable component may only be in your build tools rather than your runtime.
This is the scanner alert fatigue problem—security teams spend weeks investigating vulnerabilities that pose no actual risk, while potentially missing real threats that do matter. VEX (Vulnerability Exploitability eXchange) solves this by letting you formally document the exploitability context of vulnerabilities in your specific applications.
What is VEX?
VEX is an open standard for expressing the exploitability status of vulnerabilities in software components. Instead of just stating "this component has CVE-2024-1234," a VEX statement provides context: "CVE-2024-1234 is in component X version Y in our application, and here's why it does (or doesn't) matter in our specific context." VEX statements provide several important properties: they are machine-readable, allowing automation to parse and process them without human intervention; they are cryptographically signed, providing authenticity and integrity assurance; they are composable, capable of being linked to SBOMs and container images; and they are standardized, based on open formats like OpenVEX and CycloneDX.
The Four VEX Statement Types
Every vulnerability in a VEX statement receives one of four statuses that formally document how it affects (or does not affect) your application.
1. NOT_AFFECTED
NOT_AFFECTED status means this vulnerability does not affect your application, even though the component is present in your system. This applies when the vulnerable code path isn't reachable in your use case, the vulnerability requires a specific configuration you don't have, you're using the component in a way that doesn't trigger the vulnerability, or the vulnerable function isn't exported or accessible to your application.
Example:
Component: OpenSSL 3.0.0Vulnerability: CVE-2023-2650 (X.509 certificate validation bypass) Status: NOT_AFFECTEDReason: We use OpenSSL only for FIPS-mode encryption, not for X.509 certificate validation. The vulnerable code path is not reachable in our application.2. AFFECTED
AFFECTED status means this vulnerability affects your application and requires immediate action. This applies when the vulnerable code is reachable in your application, your specific use case triggers the vulnerability, the component must be patched or replaced, and risk mitigation is necessary.
Example:
Component: Log4j 2.14.1Vulnerability: CVE-2021-44228 (Log4Shell remote code execution) Status: AFFECTEDAction: Update to Log4j 2.17.0 or disable JNDI. We detected log4j in production environment.3. FIXED
FIXED status means the vulnerability affected your application, but you have already patched it. This applies when you previously had the vulnerable version, you have upgraded to a version containing the fix, the vulnerability is no longer a concern, and this status is useful for historical tracking and compliance documentation.
Example:
Component: Lodash 4.17.20Vulnerability: CVE-2021-23337 (Prototype pollution) Status: FIXEDFixed Version: 4.17.214. UNDER_INVESTIGATION
UNDER_INVESTIGATION status means you are still determining whether this vulnerability affects your application. This applies when the impact is unclear, you need time to analyze the specific code path, investigation is actively in progress, and a follow-up determination is expected within a specified timeframe.
Example:
Component: Django 3.2.0Vulnerability: CVE-2024-XXXXX (Theoretical SQL injection) Status: UNDER_INVESTIGATIONExpected Resolution: 48 hoursInvestigation Notes: Checking if our ORM usage path triggers the vulnerable code.OpenVEX Format
OpenVEX is the emerging standard for VEX statements, maintained as open-source. An OpenVEX statement is a JSON document linked to a container image:
{ "tooling": "CleanStart Source Intelligence Core v2.0", "author": "security-team@myorg.com", "timestamp": "2024-03-15T10:30:00Z", "statements": [ { "vulnerability": { "name": "CVE-2024-1234", "description": "Buffer overflow in libpng" }, "timestamp": "2024-03-15T10:30:00Z", "products": [ { "identifiers": { "purl": "pkg:docker/myapp@sha256:abc123..." }, "subcomponents": [ { "identifiers": { "purl": "pkg:apk/libpng@1.6.37" } } ] } ], "status": "NOT_AFFECTED", "justification": "component_not_included", "impact_statement": "libpng is not used in our application. This component appears only in build tools." }, { "vulnerability": { "name": "CVE-2021-44228" }, "products": [ { "identifiers": { "purl": "pkg:docker/java-app@sha256:def456..." } } ], "status": "AFFECTED", "actionStatement": "Update log4j to version 2.17.0 or later" } ]}VEX vs CVE vs CVSS
These are often confused because they all relate to vulnerabilities. Here's how they differ:
Aspect | CVE | CVSS | VEX |
|---|---|---|---|
Definition | Identifier for a specific vulnerability | Numerical severity score | Exploitability status in your context |
Created By | NVD/MITRE | NIST/industry teams | Your organization |
Scope | Universal (all software) | Universal (technical severity) | Organization-specific |
Example | CVE-2021-44228 | 10.0 (critical) | NOT_AFFECTED (our use case) |
Updates | Never (identifier is permanent) | May be updated with new research | Updates as you analyze |
In practice: CVE and CVSS tell you a vulnerability exists. VEX tells you whether it matters for your specific application.
Why VEX is Critical for Container Security
The following diagram shows how VEX statements filter vulnerability alerts to reveal only actionable issues:
1Scanner Input2VEX Filter Pipeline3Action ItemsContainers make VEX especially important for several reasons: First, large supply chains mean a single container image can have 100 or more transitive dependencies, creating massive scanning overhead. Second, teams use common base images where vulnerabilities may not be relevant to the actual application. Third, distroless principles teach us that vulnerabilities in build tools don't matter if those tools aren't included in the runtime image. Fourth, compliance requirements demand proof that vulnerabilities are either mitigated or formally documented as not applicable.
Consider a practical example: scanning the alpine:latest base image reveals vulnerabilities across multiple components—libssl (OpenSSL) contains CVE-2023-2650, CVE-2023-2975, and CVE-2024-0567; libcrypto has CVE-2024-1086; libc contains CVE-2023-4813; zlib has CVE-2023-45853; curl shows CVE-2024-0567; and over 200 more vulnerabilities exist elsewhere, generating a total of 243 alerts. However, with VEX statements applied, OpenSSL CVEs are marked NOT_AFFECTED because they're only used for FIPS and don't reach vulnerable code paths, the libc CVE is marked FIXED because it was patched in the build, and the curl CVE is marked NOT_AFFECTED because the HTTP client functionality is not used. This reduces actual exploitable vulnerabilities from 243 alerts down to just 3 actionable items.
CleanStart and VEX
CleanStart Source Intelligence Core automates VEX creation through multiple mechanisms. It generates VEX statements based on component usage analysis and exploit intelligence, correlates with SBOMs to understand actual component presence and data flow paths, integrates exploit intelligence from multiple security databases, contextualizes vulnerability exploitability using code path analysis, creates signatures for VEX statements using Sigstore to ensure authenticity, and maintains VEX history for compliance and audit trails. This automation reduces your security team's triage time from hours spent on each vulnerability down to just seconds.
VEX Best Practices
When implementing VEX, be precise in documenting the specific reason why a vulnerability does not affect you—generic explanations are less valuable than specific technical details. Keep statements current by updating VEX documents when your application or dependencies change. Sign statements using cryptographic signatures like Sigstore to ensure authenticity and prevent tampering. Link VEX statements to SBOMs so they reference specific components and versions. Version your statements to track changes over time for audit compliance. Use standardized justification codes when applicable, choosing from component_not_included, vulnerable_code_not_present, vulnerable_code_not_in_execute_path, vulnerable_code_not_reachable, vulnerable_code_requires_configuration, vulnerable_code_requires_dependency, vulnerable_code_requires_environment, vulnerable_code_requires_interaction, vulnerable_code_version_range_not_affected, vulnerable_code_requires_platform, or other. Automate analysis by using code analysis tools to verify your NOT_AFFECTED claims rather than relying solely on manual review. Review regularly by scheduling quarterly VEX statement reviews as dependencies change.
OpenVEX Standard References
VEX is standardized in several formats that organizations can choose based on their needs. OpenVEX is an open-source standard using JSON-LD format. CycloneDX version 1.4 and later includes VEX status fields as part of the SBOM format. SPDX version 3.0 and later provides a relationship model for expressing vulnerability status.
Related Concepts
SBOM (Software Bill of Materials) is a component inventory that VEX statements reference to provide context about which components are affected. CVE (Common Vulnerabilities and Exposures) provides unique vulnerability identifiers that VEX statements discuss. CVSS (Common Vulnerability Scoring System) provides numerical severity scores independent of context. Supply Chain Security encompasses VEX as a key mechanism for transparency about vulnerability remediation. Container Image Signing often includes signed VEX statements alongside the container image itself.
Further Reading
OpenVEX Specification - Official OpenVEX GitHub repository. NTIA VEX Resources - Government guidance on VEX adoption. CycloneDX VEX Support - VEX in SBOM formats. Vulnerability Exploitability Research - Academic work on vulnerability context.
