Vulnerabilities
An activity at the core of supply chain security is to compare the contents of a BOM, meaning all components of a product, to databases of known vulnerabilities.
For vulnerability interactions beyond reading, you need the VULN_MANAGEMENT permission. The section about Access Management describes how it is granted.
Detecting
Vendors distribute vulnerabilities in their products over a wide variety of channels:
- The Open Source Vulnerability (OSV) format is developed as a standard by Google. It is implemented by several databases, most notably the OSV database.
- The National Vulnerability Database (NVD) offers a REST API.
- The European Union Vulnerabilty Database (EUVD) offers a different REST API.
- Public GitHub repositories have a security advisories section.
- Any meaningful CSAF document refers to at least one vulnerability.
There is an important distinction between the last and the other cases: CSAF documents may be classified via a TLP label, while all other vulnerabilities are publicly available information. This is why many databases are great tools when it comes to Open Source dependencies, where vulnerabilities tend to be made publicly available, but they have shortcomings when queried for closed source products.
BOMnipotent supports both kinds of sources via different mechanisms.
Updating Public Vulnerabilities
Several good tools exist to collect vulnerabilities from public databases. BOMnipotent currently does not reimplement their functionality, but instead accepts their output.
One tool that can be used in combination with BOMnipotent is grype, which takes a BOM as input and produces a list of public vulnerabilities as output. The grype tutorial contains some additional information on its usage. Other tools can be used as long as they provide output in CycloneDX JSON format.
Using the BOMnipotent Client, you can directly print the contents of a BOM and pipe it to grype.
bomnipotent_client bom get "Your Project" "1.0.0" | grype --output cyclonedx-json=/home/vuln.cdx.jsonbomnipotent_client bom get "Your Project" "1.0.0" | grype -o cyclonedx-json=/home/vuln.cdx.jsonThis will check the software components against several databases and add the result to the CycloneDX. It then stores all that in a file called “vuln.cdx.json” (or whichever other name you provide).
Grype currently has a small known bug that makes it forget the version of the main component when it adds the vulnerabilities. This is a bit problematic because BOMnipotent needs the version to uniquely identify a product. One possible workaround is to re-add the version to the document, for example via
jq '.metadata.component.version = "<VERSION>"' "vuln.cdx.json" > "vuln_with_version.cdx.json". Starting with BOMnipotent v0.3.1 you can instead directly provide the version during the vulnerability upload, as described below.
The command to update the vulnerabilities associated with a BOM is:
bomnipotent_client vulnerability update /home/your_project/vuln.cdx.jsonbomnipotent_client vuln update /home/your_project/vuln.cdx.json[INFO] Updated vulnerabilities of BOM 'Your Project@1.0.0'.
The “<VULNERABILITIES>” argument needs to be a path to a file in CycloneDX JSON format.
Ideally, this file contains the name and version of the associated BOM, in which case they will automatically be read. If one of the values is missing (due to a known bug in grype, for example), you can provide it with an optional argument:
bomnipotent_client vulnerability update /home/your_project/vuln.cdx.json --name="Your Project" --version="1.0.0"bomnipotent_client vuln update /home/your_project/vuln.cdx.json -n "Your Project" -v "1.0.0"[INFO] Updated vulnerabilities of BOM 'Your Project@1.0.0'.
Vulnerabilities are meant to updated periodically. Doing so will completely replace any previous vulnerabilities associated a BOM. The uploaded CycloneDX document thus needs to contain a full list of all known vulnerabilities.
You can only update vulnerabilities for a BOM that exists on the server:
bomnipotent_client vulnerability update /home/your_project/vuln.cdx.json --name=Schlagsahne --version=2.7.1;
bomnipotent_client vulnerability update /home/your_project/vuln.cdx.json --version=1.0.1;bomnipotent_client vuln update /home/your_project/vuln.cdx.json -n Schlagsahne -v 2.7.1;
bomnipotent_client vuln update /home/your_project/vuln.cdx.json -v 1.0.1;[ERROR] Received response:
404 Not Found
BOM 'Schlagsahne@2.7.1' not found in database.
[ERROR] Received response:
404 Not Found
BOM 'Your Project@1.0.1' not found in database.
Updating Classified Vulnerabilities
Some vendors, especially in the industry sector, do not typically make their vulnerabilities publicly available right away. This makes sense: As soon as a vulnerability is publicly known, it can be exploited. Instead, the vendors typically inform their customers of actions they have to take, and publicise the incident only after a grace period.
The CSAF standard was developed to automate this process. Vendors upload CSAF documents on their CSAF server, which can then be periodically queried by the customers.
Beginning with version 1.5.0, BOMnipotent supports the “download_csafs” periodic task. It downloads CSAF documents from an external CSAF provider, matches them agains the components of all stored BOMs, and creates new vulnerability entries based on those matches.
CSAF documents contain an affection status for their products, which determines whether or not a vulnerability has to be created for the component. The stati “first_affected”, “last_affected”, “known_affected” and “under_investigation” create a vulnerability entry, while the stati “fixed”, “first_fixed”, “known_not_affected” and “recommended” do not.
The resulting vulnerability is itself classified. Because it is a combination of a BOM and a CSAF document, which may in general have different classifications, the stricter of the two TLP labels is used. If both documents do not provide a classification, the default TLP Label is used.
The task can be configured several times, allowing to independently query all distinct vendors of your used components.
Listing
The section about listing vulnerabilities in the documentation for consumers covers most aspects of listing vulnerabilities.
One aspect not mentioned there is the “unassessed” option. With it, BOMnipotent Client lists only those vulnerabilities that do not have a CSAF document with status “final” associated with it.
For this association to work, the CSAF document must contain product_name and product_version entries for the BOM in its branches.
bomnipotent_client vulnerability list --unassessedbomnipotent_client vuln list -u[WARN]
╭──────────────┬─────────┬─────────────────────┬───────────┬──────────────────╮
│ Product Name │ Version │ Vulnerability │ TLP │ CSAF Assessments │
├──────────────┼─────────┼─────────────────────┼───────────┼──────────────────┤
│ Best Project │ 3.1.4 │ GHSA-qg5g-gv98-5ffh │ TLP:GREEN │ │
╰──────────────┴─────────┴─────────────────────┴───────────┴──────────────────╯
[ERROR] Found 1 unassessed vulnerabilities.
In this mode, BOMnipotent Client exits with a code indicating an error if and only if there are unassessed vulnerabilites. This makes it easy to integrate this call in your periodic CI/CD.
You can freely combine this option with specifying a product name or version:
bomnipotent_client vulnerability list --name="Your Project" --version="1.0.0" --unassessedbomnipotent_client vuln list -n "Your Project" -v "1.0.0" -u[INFO] No unassessed vulnerabilities were found.