From e59d59a5af69bf9b2ab1b789cede72d53132d485 Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Sat, 1 Nov 2025 09:01:52 +0000 Subject: [PATCH 1/4] how-to-vex: Fix namespace in JSON examples - A follow-up of #6 - Rename `how-to-vex.mc` -> `how-to-vex.md`, so it can be rendered - Fix property names in the JSON example. Namespaces for non-core profile properties are required. - Fix Markdown warnings: add one blank lines around headings and lists - Remove "J" numbering from the heading, as it is no longer an appendix of the spec - Fix few typos: "metdata" -> "metadata", "logj4" -> "log4j", etc. Original PR: https://github.com/spdx/using/pull/21 Signed-off-by: Arthit Suriyawongkul --- docs/{how-to-vex.mc => how-to-vex.md} | 116 ++++++++++++++++---------- mkdocs.yml | 1 + 2 files changed, 72 insertions(+), 45 deletions(-) rename docs/{how-to-vex.mc => how-to-vex.md} (65%) diff --git a/docs/how-to-vex.mc b/docs/how-to-vex.md similarity index 65% rename from docs/how-to-vex.mc rename to docs/how-to-vex.md index 24408c5..db1bd73 100644 --- a/docs/how-to-vex.mc +++ b/docs/how-to-vex.md @@ -1,8 +1,17 @@ -# How to Implement VEX in SPDX +--- +SPDX-License-Identifier: Community-Spec-1.0 +tags: + - security + - guide + - v3.0 +--- + +# How to implement VEX in SPDX Vulnerability Exploitability eXchange (VEX) was designed to allow a software supplier or other parties to assert the status of specific vulnerabilities in a particular product. The SPDX security profile supports the communication of VEX metadata using subclassed [VEX Vulnerability Assessment Relationships](https://spdx.github.io/spdx-spec/v3.0/model/Security/Classes/VexVulnAssessmentRelationship/). SPDX uses relationships to convey the [minimum elements](https://www.cisa.gov/sites/default/files/2023-04/minimum-requirements-for-vex-508c.pdf) of a vulnerability assessment (severity, impact, exploitability). VEX centers on the notion of a statement. A statement can be defined as an assertion intersecting product, a vulnerability, and an impact status: + ```text statement = product(s) + vulnerability + status │ │ │ @@ -10,143 +19,160 @@ VEX centers on the notion of a statement. A statement can be defined as an asser we are talking about to one of the product's statuses as identified components by the VEX working group. ``` -The `product` is a piece of software that can be correlated to an entry in an SBOM. `vulnerability` is the ID of a security vulnerability as understood by scanners, which can be looked up in a vulnerability tracking system. `status` is one of the impact status labels defined by VEX (See https://www.ntia.gov/files/ntia/publications/vex_one-page_summary.pdf). -## J.1 Linking vs Embedding VEX information in SPDX +The `product` is a piece of software that can be correlated to an entry in an SBOM. `vulnerability` is the ID of a security vulnerability as understood by scanners, which can be looked up in a vulnerability tracking system. `status` is one of the impact status labels defined by VEX (See ). + +## 1. Linking vs embedding VEX information in SPDX SPDX 3.0 provides support to include VEX information in two ways: + 1) Linking to external VEX information -2) Embed VEX metdata directly in an SPDX security document +2) Embed VEX metadata directly in an SPDX security document -### J.1.1 Linking to VEX +### 1.1 Linking to VEX To link to an external VEX document, include an external reference of type `vulnerabilityExploitabilityAssessment` on the Vulnerability Element that encapsulates the CVE described in the VEX document. + ```json { - "@type": "Vulnerability", - "@id": "urn:spdx.dev:vuln-2", + "type": "security_Vulnerability", + "spdxId": "urn:spdx.dev:vuln-2", "name": "cve-1234-5678", "publishedTime": "2024-01-01T16:28:45Z", "externalRef": [ { - "@type": "ExternalRef", + "type": "ExternalRef", "externalRefType": "vulnerabilityExploitabilityAssessment", - "locator": "https://github.com/openvex/vexctl/blob/main/examples/openvex/document1.vex.json" + "locator": [ + "https://github.com/openvex/vexctl/blob/main/examples/openvex/document1.vex.json" + ] } ] } ``` -### J.1.2 Embedding VEX information in SPDX +### 1.2 Embedding VEX information in SPDX In order to embed VEX metadata in an SPDX document, you can utilize the SPDX 3.0 Security Profile. See the following sections for examples. - -## J.2 Assembling a VEX Statement +## 2. Assembling a VEX statement A VEX statement is assembled by a triad of (at least): ```a software product + a vex status + a vulnerability``` In SPDX the VEX product can be any software package. There are four VEX status labels, each of which is represented in SPDX with a subclassed VEX Relationship: -| VEX Status | SPDX VEX Relationship | + +| VEX status | SPDX VEX Relationship | | --- | --- | | not_affected | [VexNotAffectedVulnAssessmentRelationship](https://spdx.github.io/spdx-spec/v3.0/model/Security/Classes/VexNotAffectedVulnAssessmentRelationship/) | | affected | [VexAffectedVulnAssessmentRelationship](https://spdx.github.io/spdx-spec/v3.0/model/Security/Classes/VexAffectedVulnAssessmentRelationship/) | | fixed | [VexFixedVulnAssessmentRelationship](https://spdx.github.io/spdx-spec/v3.0/model/Security/Classes/VexFixedVulnAssessmentRelationship/) | -| under_investigation | [VexUnderInvestigationVulnAssessmentRelationship](https://spdx.github.io/spdx-spec/v3.0/model/Security/Classes/VexUnderInvestigationVulnAssessmentRelationship/) | +| under_investigation | [VexUnderInvestigationVulnAssessmentRelationship](https://spdx.github.io/spdx-spec/v3.0/model/Security/Classes/VexUnderInvestigationVulnAssessmentRelationship/) | -For all VEX Relationships, the `from` element must be a [Vulnerability](https://spdx.github.io/spdx-spec/v3.0/model/Security/Classes/Vulnerability/) and the `to` end of the relationship must point to one or more elements that represent the VEX product(s). +For all VEX Relationships, the `from` element must be a [Vulnerability](https://spdx.github.io/spdx-spec/v3.0/model/Security/Classes/Vulnerability/) and the `to` end of the relationship must point to one or more elements that represent the VEX product(s). VEX inherits information from the document level down to its statements. When a statement is missing information it can be completed by reading the equivalent field from the containing document. For example, if a VEX relationship is missing data in its createdBy property, tools must consider the entity listed in the CreationInfo section of the document as the VEX author. In the same way, when a VEX relationship does not have a created property, the document's date must be considered as authoritative. The following example shows how you would communicate that a vulnerability is under investigation to determine whether or not it affects a software product. ```json - "@type": "VexUnderInvestigationVulnAssessmentRelationship", - "@id": "urn:spdx.dev:vex-underInvestigation-1", +{ + "type": "VexUnderInvestigationVulnAssessmentRelationship", + "spdxId": "urn:spdx.dev:vex-underInvestigation-1", "relationshipType": "underInvestigationFor", "from": "urn:spdx.dev:vuln-cve-2020-28498", "to": ["urn:product-acme-application-1.3"], - "assessedElement": "urn:npm-elliptic-6.5.2", + "security_assessedElement": "urn:npm-elliptic-6.5.2", "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], "publishedTime": "2021-03-09T11:04:53Z" +} ``` To communicate that a product is affected by a vulnerability, you would instead use the `VexAffectedVulnAssessmentRelationship`: ```json - "@type": "VexAffectedVulnAssessmentRelationship", - "@id": "urn:spdx.dev:vex-affected-1", +{ + "type": "VexAffectedVulnAssessmentRelationship", + "spdxId": "urn:spdx.dev:vex-affected-1", "relationshipType": "affects", "from": "urn:spdx.dev:vuln-cve-2020-28498", "to": ["urn:product-acme-application-1.3"], - "assessedElement": "urn:npm-elliptic-6.5.2", + "security_assessedElement": "urn:npm-elliptic-6.5.2", "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], "publishedTime": "2021-03-09T11:04:53Z" +} ``` -VEX relationships in SPDX will always point `to` element(s) representing the VEX *products*. A product is a logical unit representing a piece of software, typically composed of one or more software packages/libraries/components. To specify an element (typially a software package) contained *in* a product where the vulnerability was detected, the VEX relationship can optionally specify this subcomponent using the [assessedElement](https://spdx.github.io/spdx-spec/v3.0/model/Security/Properties/assessedElement/) property. Using the `assessedElement` can be helful in situations where a particular CVE may affect software products differently. For example, perhaps you have two software products which both contain the log4j vulnerability (CVE-2021-44228) but only one of the products is exploitable by the vulnerability. The `to` product in your SPDX VEX statements and the VEX status relationships would be different but the `assessedElement` would be the same log4j package. +VEX relationships in SPDX will always point `to` element(s) representing the VEX *products*. A product is a logical unit representing a piece of software, typically composed of one or more software packages/libraries/components. To specify an element (typically a software package) contained *in* a product where the vulnerability was detected, the VEX relationship can optionally specify this subcomponent using the [assessedElement](https://spdx.github.io/spdx-spec/v3.0/model/Security/Properties/assessedElement/) property. Using the `assessedElement` can be helpful in situations where a particular CVE may affect software products differently. For example, perhaps you have two software products which both contain the log4j vulnerability (CVE-2021-44228) but only one of the products is exploitable by the vulnerability. The `to` product in your SPDX VEX statements and the VEX status relationships would be different but the `assessedElement` would be the same log4j package. Product A, affected by CVE-2021-44228: + ```json - "@type": "VexAffectedVulnAssessmentRelationship", - "@id": "urn:spdx.dev:vex-affected-1", +{ + "type": "VexAffectedVulnAssessmentRelationship", + "spdxId": "urn:spdx.dev:vex-affected-1", "relationshipType": "affects", "from": "urn:spdx.dev:vuln-cve-2021-44228", "to": ["urn:product-acme-application-1.3"], - "assessedElement": "urn:apache-log4j-2.12", + "security_assessedElement": "urn:apache-log4j-2.12", "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], "publishedTime": "2021-12-10T11:04:53Z", - "actionStatement": "Recommend to update logj4 version to 2.16.0 or later" - "actionStatementTime": "2021-12-12T12:09:23Z" + "security_actionStatement": "Recommend to update log4j version to 2.16.0 or later", + "security_actionStatementTime": "2021-12-12T12:09:23Z" +} ``` Product B, not affected by CVE-2021-44228: + ```json - "@type": "VexNotAffectedVulnAssessmentRelationship", - "@id": "urn:spdx.dev:vex-not-affected-1", +{ + "type": "VexNotAffectedVulnAssessmentRelationship", + "spdxId": "urn:spdx.dev:vex-not-affected-1", "relationshipType": "doesNotAffect", "from": "urn:spdx.dev:vuln-cve-2021-44228", "to": ["urn:product-acme-application-1.4"], - "assessedElement": "urn:apache-log4j-2.12", + "security_assessedElement": "urn:apache-log4j-2.12", "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], "publishedTime": "2021-12-10T11:04:53Z", - "justificationType": "vulnerableCodeNotInExecutePath" + "security_justificationType": "vulnerableCodeNotInExecutePath" +} ``` - - -## J.3 Changing the Status of a Vulnerability +## 3. Changing the status of a vulnerability VEX is designed to communicate status of a vulnerability in a software product which is inherently dynamic and prone to change over time. -Because [Elements](https://spdx.github.io/spdx-spec/v3.0/model/Core/Classes/Element/) in SPDX are immutable, it is best best practice to issue a new VulnAssessmentRelationship of type `amendedBy` each time the VEX status of a vulnerability changes (i.e. `underInvestigationFor` --> `affects`) in addition to creating the new type of VEX status relationship. Linking the two VEX relationships this way creates a more complete graph while making it easier for tools to track the changing status of a vulnerability in a software product. The following example shows how you would communicate that a vulnerability was under investigation before determining that the vulnerability indeed affects a product. +Because [Elements](https://spdx.github.io/spdx-spec/v3.0/model/Core/Classes/Element/) in SPDX are immutable, it is best practice to issue a new VulnAssessmentRelationship of type `amendedBy` each time the VEX status of a vulnerability changes (i.e. `underInvestigationFor` --> `affects`) in addition to creating the new type of VEX status relationship. Linking the two VEX relationships this way creates a more complete graph while making it easier for tools to track the changing status of a vulnerability in a software product. The following example shows how you would communicate that a vulnerability was under investigation before determining that the vulnerability indeed affects a product. ```json - "@type": "VexUnderInvestigationVulnAssessmentRelationship", - "@id": "urn:spdx.dev:vex-underInvestigation-1", +{ + "type": "VexUnderInvestigationVulnAssessmentRelationship", + "spdxId": "urn:spdx.dev:vex-underInvestigation-1", "relationshipType": "underInvestigationFor", "from": "urn:spdx.dev:vuln-cve-2020-28498", "to": ["urn:product-acme-application-1.3"], - "assessedElement": "urn:npm-elliptic-6.5.2", + "security_assessedElement": "urn:npm-elliptic-6.5.2", "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], "publishedTime": "2021-03-09T11:04:53Z" - - "@type": "VulnAssessmentRelationship", - "@id": "urn:spdx.dev:vex-update-acme-1.3", +}, +{ + "type": "VulnAssessmentRelationship", + "spdxId": "urn:spdx.dev:vex-update-acme-1.3", "relationshipType": "amendedBy", "from": "urn:spdx.dev:vex-underInvestigation-1", "to": ["urn:spdx.dev:vex-affected-1"], - - "@type": "VexAffectedVulnAssessmentRelationship", - "@id": "urn:spdx.dev:vex-affected-1", +}, +{ + "type": "VexAffectedVulnAssessmentRelationship", + "spdxId": "urn:spdx.dev:vex-affected-1", "relationshipType": "affects", "from": "urn:spdx.dev:vuln-cve-2020-28498", "to": ["urn:product-acme-application-1.3"], - "assessedElement": "urn:npm-elliptic-6.5.2", + "security_assessedElement": "urn:npm-elliptic-6.5.2", "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], "publishedTime": "2021-03-15T08:10:43Z" +} ``` Note that it is not required to include an `amendedBy` relationship for evolving impact statements but it is considered best practice. One could also simply create a new VEX status relationship for tools/consumers to piece together using context clues like product names, ids and time stamps. diff --git a/mkdocs.yml b/mkdocs.yml index f3faf89..409932f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -48,6 +48,7 @@ nav: - Getting started: getting-started.md - Cross referencing: cross-reference.md - Including security information in a SPDX document: security-info-in-spdx.md +- How to implement VEX in SPDX: how-to-vex.md - Using SPDX License List short identifiers in source files: license-id-in-source.md - Using SPDX to comply with norms, standards and regulation: comply-with-norms.md - Differences from previous editions: diffs-from-previous-editions.md From 1bbd2e655b731df7ad581b7d1d3633e8e815b207 Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Sat, 1 Nov 2025 09:10:41 +0000 Subject: [PATCH 2/4] Fix JSON + add metadata Signed-off-by: Arthit Suriyawongkul --- docs/how-to-vex.md | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/docs/how-to-vex.md b/docs/how-to-vex.md index db1bd73..84fa6b0 100644 --- a/docs/how-to-vex.md +++ b/docs/how-to-vex.md @@ -1,4 +1,7 @@ --- +SPDX-FileContributor: Rose Judge +SPDX-FileContributor: SPDX Contributors +SPDX-FileType: DOCUMENTATION SPDX-License-Identifier: Community-Spec-1.0 tags: - security @@ -82,9 +85,9 @@ The following example shows how you would communicate that a vulnerability is un "spdxId": "urn:spdx.dev:vex-underInvestigation-1", "relationshipType": "underInvestigationFor", "from": "urn:spdx.dev:vuln-cve-2020-28498", - "to": ["urn:product-acme-application-1.3"], + "to": [ "urn:product-acme-application-1.3" ], "security_assessedElement": "urn:npm-elliptic-6.5.2", - "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], + "suppliedBy": [ "urn:spdx.dev:agent-jane-doe" ], "publishedTime": "2021-03-09T11:04:53Z" } ``` @@ -97,9 +100,9 @@ To communicate that a product is affected by a vulnerability, you would instead "spdxId": "urn:spdx.dev:vex-affected-1", "relationshipType": "affects", "from": "urn:spdx.dev:vuln-cve-2020-28498", - "to": ["urn:product-acme-application-1.3"], + "to": [ "urn:product-acme-application-1.3" ], "security_assessedElement": "urn:npm-elliptic-6.5.2", - "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], + "suppliedBy": [ "urn:spdx.dev:agent-jane-doe" ], "publishedTime": "2021-03-09T11:04:53Z" } ``` @@ -114,9 +117,9 @@ Product A, affected by CVE-2021-44228: "spdxId": "urn:spdx.dev:vex-affected-1", "relationshipType": "affects", "from": "urn:spdx.dev:vuln-cve-2021-44228", - "to": ["urn:product-acme-application-1.3"], + "to": [ "urn:product-acme-application-1.3" ], "security_assessedElement": "urn:apache-log4j-2.12", - "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], + "suppliedBy": [ "urn:spdx.dev:agent-jane-doe" ], "publishedTime": "2021-12-10T11:04:53Z", "security_actionStatement": "Recommend to update log4j version to 2.16.0 or later", "security_actionStatementTime": "2021-12-12T12:09:23Z" @@ -131,9 +134,9 @@ Product B, not affected by CVE-2021-44228: "spdxId": "urn:spdx.dev:vex-not-affected-1", "relationshipType": "doesNotAffect", "from": "urn:spdx.dev:vuln-cve-2021-44228", - "to": ["urn:product-acme-application-1.4"], + "to": [ "urn:product-acme-application-1.4" ], "security_assessedElement": "urn:apache-log4j-2.12", - "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], + "suppliedBy": [ "urn:spdx.dev:agent-jane-doe" ], "publishedTime": "2021-12-10T11:04:53Z", "security_justificationType": "vulnerableCodeNotInExecutePath" } @@ -151,9 +154,9 @@ Because [Elements](https://spdx.github.io/spdx-spec/v3.0/model/Core/Classes/Elem "spdxId": "urn:spdx.dev:vex-underInvestigation-1", "relationshipType": "underInvestigationFor", "from": "urn:spdx.dev:vuln-cve-2020-28498", - "to": ["urn:product-acme-application-1.3"], + "to": [ "urn:product-acme-application-1.3" ], "security_assessedElement": "urn:npm-elliptic-6.5.2", - "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], + "suppliedBy": [ "urn:spdx.dev:agent-jane-doe" ], "publishedTime": "2021-03-09T11:04:53Z" }, { @@ -161,16 +164,16 @@ Because [Elements](https://spdx.github.io/spdx-spec/v3.0/model/Core/Classes/Elem "spdxId": "urn:spdx.dev:vex-update-acme-1.3", "relationshipType": "amendedBy", "from": "urn:spdx.dev:vex-underInvestigation-1", - "to": ["urn:spdx.dev:vex-affected-1"], + "to": [ "urn:spdx.dev:vex-affected-1" ] }, { "type": "VexAffectedVulnAssessmentRelationship", "spdxId": "urn:spdx.dev:vex-affected-1", "relationshipType": "affects", "from": "urn:spdx.dev:vuln-cve-2020-28498", - "to": ["urn:product-acme-application-1.3"], + "to": [ "urn:product-acme-application-1.3" ], "security_assessedElement": "urn:npm-elliptic-6.5.2", - "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], + "suppliedBy": [ "urn:spdx.dev:agent-jane-doe" ], "publishedTime": "2021-03-15T08:10:43Z" } ``` From 9a2101eeef14cfe4425718131f2d1ce237627c4d Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Sat, 1 Nov 2025 09:20:11 +0000 Subject: [PATCH 3/4] Put multiple elements in array Signed-off-by: Arthit Suriyawongkul --- docs/how-to-vex.md | 56 ++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/docs/how-to-vex.md b/docs/how-to-vex.md index 84fa6b0..ef0a6fb 100644 --- a/docs/how-to-vex.md +++ b/docs/how-to-vex.md @@ -149,33 +149,35 @@ VEX is designed to communicate status of a vulnerability in a software product w Because [Elements](https://spdx.github.io/spdx-spec/v3.0/model/Core/Classes/Element/) in SPDX are immutable, it is best practice to issue a new VulnAssessmentRelationship of type `amendedBy` each time the VEX status of a vulnerability changes (i.e. `underInvestigationFor` --> `affects`) in addition to creating the new type of VEX status relationship. Linking the two VEX relationships this way creates a more complete graph while making it easier for tools to track the changing status of a vulnerability in a software product. The following example shows how you would communicate that a vulnerability was under investigation before determining that the vulnerability indeed affects a product. ```json -{ - "type": "VexUnderInvestigationVulnAssessmentRelationship", - "spdxId": "urn:spdx.dev:vex-underInvestigation-1", - "relationshipType": "underInvestigationFor", - "from": "urn:spdx.dev:vuln-cve-2020-28498", - "to": [ "urn:product-acme-application-1.3" ], - "security_assessedElement": "urn:npm-elliptic-6.5.2", - "suppliedBy": [ "urn:spdx.dev:agent-jane-doe" ], - "publishedTime": "2021-03-09T11:04:53Z" -}, -{ - "type": "VulnAssessmentRelationship", - "spdxId": "urn:spdx.dev:vex-update-acme-1.3", - "relationshipType": "amendedBy", - "from": "urn:spdx.dev:vex-underInvestigation-1", - "to": [ "urn:spdx.dev:vex-affected-1" ] -}, -{ - "type": "VexAffectedVulnAssessmentRelationship", - "spdxId": "urn:spdx.dev:vex-affected-1", - "relationshipType": "affects", - "from": "urn:spdx.dev:vuln-cve-2020-28498", - "to": [ "urn:product-acme-application-1.3" ], - "security_assessedElement": "urn:npm-elliptic-6.5.2", - "suppliedBy": [ "urn:spdx.dev:agent-jane-doe" ], - "publishedTime": "2021-03-15T08:10:43Z" -} +[ + { + "type": "VexUnderInvestigationVulnAssessmentRelationship", + "spdxId": "urn:spdx.dev:vex-underInvestigation-1", + "relationshipType": "underInvestigationFor", + "from": "urn:spdx.dev:vuln-cve-2020-28498", + "to": [ "urn:product-acme-application-1.3" ], + "security_assessedElement": "urn:npm-elliptic-6.5.2", + "suppliedBy": [ "urn:spdx.dev:agent-jane-doe" ], + "publishedTime": "2021-03-09T11:04:53Z" + }, + { + "type": "VulnAssessmentRelationship", + "spdxId": "urn:spdx.dev:vex-update-acme-1.3", + "relationshipType": "amendedBy", + "from": "urn:spdx.dev:vex-underInvestigation-1", + "to": [ "urn:spdx.dev:vex-affected-1" ] + }, + { + "type": "VexAffectedVulnAssessmentRelationship", + "spdxId": "urn:spdx.dev:vex-affected-1", + "relationshipType": "affects", + "from": "urn:spdx.dev:vuln-cve-2020-28498", + "to": [ "urn:product-acme-application-1.3" ], + "security_assessedElement": "urn:npm-elliptic-6.5.2", + "suppliedBy": [ "urn:spdx.dev:agent-jane-doe" ], + "publishedTime": "2021-03-15T08:10:43Z" + } +] ``` Note that it is not required to include an `amendedBy` relationship for evolving impact statements but it is considered best practice. One could also simply create a new VEX status relationship for tools/consumers to piece together using context clues like product names, ids and time stamps. From be788b98c294ae8c63e8d245d45b5f272dc27df5 Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Sat, 1 Nov 2025 09:22:25 +0000 Subject: [PATCH 4/4] Put each element in its own code block Signed-off-by: Arthit Suriyawongkul --- docs/how-to-vex.md | 62 ++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/docs/how-to-vex.md b/docs/how-to-vex.md index ef0a6fb..1614e1c 100644 --- a/docs/how-to-vex.md +++ b/docs/how-to-vex.md @@ -149,35 +149,39 @@ VEX is designed to communicate status of a vulnerability in a software product w Because [Elements](https://spdx.github.io/spdx-spec/v3.0/model/Core/Classes/Element/) in SPDX are immutable, it is best practice to issue a new VulnAssessmentRelationship of type `amendedBy` each time the VEX status of a vulnerability changes (i.e. `underInvestigationFor` --> `affects`) in addition to creating the new type of VEX status relationship. Linking the two VEX relationships this way creates a more complete graph while making it easier for tools to track the changing status of a vulnerability in a software product. The following example shows how you would communicate that a vulnerability was under investigation before determining that the vulnerability indeed affects a product. ```json -[ - { - "type": "VexUnderInvestigationVulnAssessmentRelationship", - "spdxId": "urn:spdx.dev:vex-underInvestigation-1", - "relationshipType": "underInvestigationFor", - "from": "urn:spdx.dev:vuln-cve-2020-28498", - "to": [ "urn:product-acme-application-1.3" ], - "security_assessedElement": "urn:npm-elliptic-6.5.2", - "suppliedBy": [ "urn:spdx.dev:agent-jane-doe" ], - "publishedTime": "2021-03-09T11:04:53Z" - }, - { - "type": "VulnAssessmentRelationship", - "spdxId": "urn:spdx.dev:vex-update-acme-1.3", - "relationshipType": "amendedBy", - "from": "urn:spdx.dev:vex-underInvestigation-1", - "to": [ "urn:spdx.dev:vex-affected-1" ] - }, - { - "type": "VexAffectedVulnAssessmentRelationship", - "spdxId": "urn:spdx.dev:vex-affected-1", - "relationshipType": "affects", - "from": "urn:spdx.dev:vuln-cve-2020-28498", - "to": [ "urn:product-acme-application-1.3" ], - "security_assessedElement": "urn:npm-elliptic-6.5.2", - "suppliedBy": [ "urn:spdx.dev:agent-jane-doe" ], - "publishedTime": "2021-03-15T08:10:43Z" - } -] +{ + "type": "VexUnderInvestigationVulnAssessmentRelationship", + "spdxId": "urn:spdx.dev:vex-underInvestigation-1", + "relationshipType": "underInvestigationFor", + "from": "urn:spdx.dev:vuln-cve-2020-28498", + "to": [ "urn:product-acme-application-1.3" ], + "security_assessedElement": "urn:npm-elliptic-6.5.2", + "suppliedBy": [ "urn:spdx.dev:agent-jane-doe" ], + "publishedTime": "2021-03-09T11:04:53Z" +} +``` + +```json +{ + "type": "VulnAssessmentRelationship", + "spdxId": "urn:spdx.dev:vex-update-acme-1.3", + "relationshipType": "amendedBy", + "from": "urn:spdx.dev:vex-underInvestigation-1", + "to": [ "urn:spdx.dev:vex-affected-1" ] +} +``` + +```json +{ + "type": "VexAffectedVulnAssessmentRelationship", + "spdxId": "urn:spdx.dev:vex-affected-1", + "relationshipType": "affects", + "from": "urn:spdx.dev:vuln-cve-2020-28498", + "to": [ "urn:product-acme-application-1.3" ], + "security_assessedElement": "urn:npm-elliptic-6.5.2", + "suppliedBy": [ "urn:spdx.dev:agent-jane-doe" ], + "publishedTime": "2021-03-15T08:10:43Z" +} ``` Note that it is not required to include an `amendedBy` relationship for evolving impact statements but it is considered best practice. One could also simply create a new VEX status relationship for tools/consumers to piece together using context clues like product names, ids and time stamps.