Note: For the sake of clarity, much of the below text is taken directly from the report Whiplash: Turning SBOM Guidelines From Text Books Into Playbooks along with various CISA documents.
SBOMs are great, however they lack critical information surrounding vulnerabilities, patches, and other software modifications that create blindspots for PSIRT and product assurance teams who need to understand each device’s security posture within its digital environment.
While it is ideal to have no vulnerabilities exist within a device, it is nearly impossible considering the amount of open source software, custom OSS and proprietary code that are all packaged together for the first time. Practitioners know that upon scanning an SBOM, it’s likely that vulnerabilities will exist within the device.
Why it’s crucial to understand CISA’s VEX Minimum Requirements
Understanding CISA’s SBOM & VEX reporting minimums allows for manufacturers to better manage vulnerability reporting upon discovery. Some will be critical, others will be high risk, and many will be irrelevant. However, beyond CVE and CWE scoring, it is up to manufacturers to prioritize and communicate detected vulnerabilities, based on device-specific contextualized data.
Even irrelevant vulnerabilities, such as those that are only present when coupled with a specific component you didn’t use or one that was mitigated using custom code by a supplier, may still need to be reported to a customer or agency. Relying on automation, this can quickly be achieved through the development of a VEX document, which according to CISA, must break down the vulnerability and details surrounding it.
What are CISA's VEX minimum requirements?
Minimum requirements
- A VEX document is a container object holding one or more VEX statements.
- A VEX document MUST contain at least one VEX statement.
- A VEX document MUST provide required VEX document metadata and MAY provide other data.
While the first two are quite obvious and lays a foundation for what a VEX document should contain, the third one dives into details that will define a CISA-recognized VEX document.
VEX data elements
Metadata is made up of multiple data points, allowing product security teams and PSIRT to quickly “read between the lines” of a Deployed or Runtime SBOM. While developers and teams should be including VEX statements and metadata in SBOM types 1-4 (from Design through Analyzed), device owners or operators should remember that these may be incomplete or premature as a source of truth to assess risk.
Document data
According to CISA, VEX document metadata should “To the greatest extent possible, VEX metadata is defined and maintained at the VEX document level. When appropriate and necessary, VEX metadata is defined at the VEX statement level. VEX document metadata MAY be synthesized or derived from VEX statement metadata; for example, [doc_time_last_updated] MUST be at least as recent as the newest [statement_time_last_updated]. VEX document metadata MUST accurately apply to all contained VEX statements.”
What this means is just like many other legal documents, the naming conventions and identifying information should remain connected to only that document, stating the document’s purpose, the component it relates to, the last time it was updated, and apply to all following information that the reader is about to review.
Like many documents that we’ve seen from CISA, FDA, and other federal bodies, the minimum information is a mix of required information, identified as “MUST” and strongly recommended guidelines, appearing as “SHOULD” or “MAY”.
Document ID [doc_id]
- Must include one document ID
- This ID should state who the author is as a point of contact if any stakeholder throughout the product lifecycle has questions.
- This will be identified as [author] / [doc_id]
ProdSec takeaway
The author does not have to give out their true identity to all stakeholders. Instead, according to CISA, they should create their own document naming convention, choose a naming ID for themselves, and cryptographically using digital signatures.
It is recommended that the convention to be followed will be [author]/[doc_id] or [author] / [doc_id] / [statement_id].
Document Version [doc_version]
- The document must include at least one version number
- Version must change and be updated with each new document change and;
- Must convey positive incremental change
ProdSec takeaway
The version number is as important as the document ID and even as important as the information within the document. Used as a beacon for the exact product that needs attention, document version accuracy will streamline vulnerability management and cut down on remediation during a time of crisis.
Author Role [author_role]
- The document may specify the role of the author
- The author may choose to use an identifying category, such as coordinator, discoverer, other, translator, user, vendor, or others as defined by CSAF 2.0.
ProdSec takeaway
The level of authority from the author will be most useful during peacetime, as PSIRT teams and product security teams deem the best course of action should a threat occur.
Tooling [tooling]
- May specify tools or automated VEX generation to generate VEX documents, VEX statements, or other VEX information.
ProdSec takeaway
Using a tool to generate the VEX report is an acceptable contradiction [author_role]. However, the VEX report must state how the document was generated.
Timestamp first issued [doc_time_first_issued]
A VEX document must provide the date and time that the VEX document was first issued.
[doc_time_first_isued] must equal the oldest [statement_time_first_issued] of all included VEX statements.
ProdSec takeaway
Being able to understand the age of a document goes back to the attestation form (Section 1) that is required by software suppliers who provide services for the US government and military. Being able to trace back the document to its earliest origins also determines the trustworthiness of the document. It should then be continuously updated from that point forward in line with [doc_version].
VEX Statement
- A VEX statement is a declaration that must convey a single [status] that applies to a single [vul_id] for one or more [product_id]s.
- A VEX statement must be logically contained within a VEX document.
- A VEX statement must exist only within one VEX document, that is, VEX statements are logically local to their containing VEX document.
ProdSec takeaway
This statement is part of the VEX document, containing insight into a specific vulnerability being addressed and only applies to the specific vulnerability being addressed. This minimized confusion allows teams to focus on the matter at hand instead of trying to confirm if the statement is applicable to a specific vulnerability.
VEX Metadata
VEX metadata is best stored within the VEX document and ideally will be specific to the relevant VEX statement.
Statement ID [statement_id]
- [statement_id] uniquely identifies a VEX statement within a VEX document.
- A VEX statement must be able to be specifically referenced within a VEX document.
- A VEX statement should provide one [statement_id].
- [statement_id] should be created within the [author] and [doc_id] namespaces and may be generated from other VEX information, for example, [author] / [doc_id] / [statement_id].
- [statement_id] may minimally be an index of VEX statements within the scope of [doc_id].
ProdSec takeaway
Just as with [document_id], keeping records of activities is the name of the game. Just as was done for the entire document, the statement should have a record of what the problem is, who is addressing it, and reference the original VEX document that the statement came from.
Statement Version [statement_version]
- [statement_version] indicates the version of the VEX statement.
- A VEX statement must provide one [statement_version].
- [statement_version] must clearly convey positive incremental change.
- [statement_version] must be incremented when any content within the VEX statement changes.
- [statement_version] may be derived from or otherwise be related to [document_version].
ProdSec takeaway
Similar to what was mentioned above regarding document versions, knowing which version of the statement that’s being read is important, especially as a reference point in relation to [statement_time_first_issued] and [statement_time_last_updated].
Timestamp first issued [statement_time_first_issued]
- A VEX statement must provide the date and time that the VEX statement was first issued.
- [statement_time_first_issued] may be derived from or otherwise related to [doc_time_first_issued].
- [statement_time_first_issued] may be derived from or otherwise related to [impact_statement_time] or [action_statement_time].
ProdSec takeaway
A statement first issued may be different from the document’s time of first issue as vulnerabilities may be related but found at a later date or another similar discovery. Identifying the first issued statement creates a timeline for product security teams to track progress over time and understand how new vulnerabilities are appearing across their devices.
Timestamp last updated [statement_time_last_updated]
- A VEX statement must provide the date and time that the VEX statement was last modified.
- [statement_time_last_updated] must initially be equivalent to [statement_time_first_issued].
- [statement_time_last_updated] may be derived from or otherwise related to [impact_statement_time] or [action_statement_time].
- [statement_time_last_updated] must be equivalent to or newer than the most recent [impact_statement_time] or [action_statement_time].
ProdSec takeaway
This should be updated with each iteration of the VEX statement, ensuring that information pulled by PSIRT or maintenance teams is up to date and ready to be used without needed verification later on to confirm it is an up to date statement.
Vulnerability Exploitability Exchange Guidelines for a Whole Product
Below are the guidelines for a VEX surrounding a whole product. Unlike SBOMs that are created pre-deployment, later-stage SBOMs must be able to point towards the vulnerability’s relevance within a greater product system.
Similar to the “may”, “must”, and “should” statements of VEX documents and VEX statements, the product details will contain the below information.
Product details
- Product details identifies and describes the products or components in a VEX statement.
- Product details must include one or more [product_id] and may include one or more [subcomponent_id].
- [product_id] and [subcomponent_id] should use existing and well-known identifiers.
- [product_id and [subcomponent_id] should reference existing SBOM identifiers.
- [product_id] and [subcomponent_id] should conform to reasonable and current conventions, for example, follow a “supplier/product/version” construct.
- [product_id] and [subcomponent_id] may be URIs, URLs, hashes, commit IDs, versions, version ranges, dates, date ranges, or any other identification system.
- [product_id] and [subcomponent_id] may be arbitrarily created by the [author].
- [product_id] and [subcomponent_id] may specify sets of products or components, for example:
- Every product or component owned by a supplier
- A product family or product line
- Version ranges
- A specific branch
Product identifier [product_id]
- [product_id] must identify the product or component that [vul_id] and [status] applies to.
- [product_id] may specify a set of products or components and MUST specify at least one of:
- [subcomponent_id]
- A component (often a sub-component of a product)
- A product, for example, a final good assembled
- A set of products or components, for example, a product line or family
- A supplier (indicating the set of all products or components from the supplier)
Subcomponent identifier [subcomponent_id]
- A VEX statement may include one or more identifiers for subcomponents associated with vulnerability details.
- A VEX statement asserts the [status] of [product_id] with respect to [vul_id].
- A VEX statement may also convey that [subcomponent_id] is included in [product_id].
- A common VEX use case is to convey that [subcomponent_id] is “affected” by [vul_id] while [product_id] is “not_affected” by [vul_id].
- [subcomponent_id] may be derived from [product_id], particularly if [product_id] is associated with SBOM or other references that convey dependencies.
- [subcomponent_id] may be derived from [vul_id] or [vul_description].
Supplier [supplier]
- Product details should identify the [supplier] of [product_id] or [subcomponent_id].
- [supplier] must clearly indicate the [product_id] or [subcomponent_id] to which [supplier] applies. For example:
- [supplier] / [product_id]
- [supplier] / [subcomponent_id]
Vulnerability details
Vulnerability details identify and provide information about the vulnerability in a VEX statement.
- Vulnerability identifier [vul_id] [vul_id] identifies the vulnerability in a VEX statement.
- A VEX statement must specify one [vul_id].
- [vul_id] SHOULD use existing, readily available, and well-known identifiers such as: CVE, the Global Security Database (GSD), or a supplier’s vulnerability identification system. It is expected that vulnerability identification systems are external to and maintained separately from VEX.
- [vul_id] may be URIs or URLs.
- [vul_id] may be arbitrary and MAY be created by the [author]. 2.6.2 Description [vul_description] A VEX statement must include or reference one [vul_description] that corresponds to [vul_id].
- [vul_description] must either be included in the VEX statement or made available to VEX consumers (for example, through a URL).
ProdSec takeaway
Documentation, such as necessary for documents and statements, is only valuable if it can be easily shared and digested by third-parties. In order for this to happen, teams must use common references, such as CVE or GSD identifiers and make the VEX reports readily available.
It is recommended to keep a living and dynamic VEX report available online so it can be updated in real time without worrying about delivering new documents to each stakeholder.
Vulnerability status
Turning VEX reports from stand alone documents to actionable reports requires the ability for stakeholders to immediately understand the state of the vulnerability they are faced with. “Is the vulnerability relevant?” and “How active is the component and what does it mean to my product?” are just two questions that CISA wants answered.
The report must state either:
- Not effected (“not_effected”) – No remediation or mitigation is required. The vulnerability does not affect the listed [product_id]s
- Affected (“affected”) – Actions are recommended by [author] to remediate, mitigate, or otherwise address [vul_id]. The vulnerability affects the listed [product_id]s.
- For status “affected”, a VEX statement must include one [action_statement] that should describe actions to remediate or mitigate [vul_id].
- Fixed (“fixed”) – The listed [product_id]s contain fixes for [vul_id].
- Under Investigation (“under_investigation”) – The [author] of the VEX statement or other relevant parties are investigating and have not yet declared a final [status].
- It is expected that [status] “under_investigation” will change once the investigation has reached a conclusion.
Impact statement [impact_statement]
For [status] “not_affected”, if [justification] is not provided, then a VEX statement MUST provide an [impact_statement] that further explains how or why the listed [product_id]s are “not_affected” by [vul_id].
If [justification] is provided, then a VEX statement MAY provide an [impact_statement].
Timestamp of impact statement [impact_statement_time]
[impact_statement] MAY include [impact_statement_time], recording when the [impact_statement] was issued.
Justification [justification]
-
- For [status] “not_affected”, a VEX statement should provide [justification].
- If [justification] is not provided then [impact_statement] must be provided.
- [justification] MUST be one of the following values:
- “Component_not_present”– The vulnerable [subcomponent_id] is not included in [product_id].
- “Vulnerable_code_not_present”– The vulnerable [subcomponent_id] is included in [product_id] but the vulnerable code is not present. Typically, this case occurs when source code is configured or built in a way that excludes the vulnerable code.
- “Vulnerable_code_not_in_execute_path”– The vulnerable code (likely in [subcomponent_id]) cannot be executed due to the way it is used by [product_id]. Typically, this case occurs when [product_id] includes the vulnerable code but does not call or otherwise use it.
- “Vulnerable_code_cannot_be_controlled_by_adversary”– The vulnerable code is present and used by [product_id] but cannot be controlled by an attacker to exploit the vulnerability.
- “Inline_mitigations_already_exist”– [product_id] includes built-in protections or features that prevent exploitation of the vulnerability. These built-in protections cannot be subverted by the attacker and cannot be configured or disabled by the user. These mitigations completely prevent exploitation based on known attack vectors.
Whether meeting government vulnerability management requirements or sharing information amongst customers, the smoothest journey from concept to SBOMs as a product security tool, begins with a secure-by-design mindset.
Organizations that prioritize having ProdSec team members in the loop as soon as code is being prepared will benefit from better quality products, a reputation of trust, and greater business opportunities.
To dive into how VEX and SBOMs are part of a greater product security and regulations strategy, read Whiplash: Turning SBOM Guidelines From Text Books Into Playbooks.