diff --git a/README.md b/README.md index 6d986e86..803cd05c 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ # sbom-utility -This utility was designed to be an API platform to validate, analyze and edit **Bills-of-Materials (BOMs)**. Primarily, it was created to validate **CycloneDX** or **SPDX-formatted** BOMs against versioned JSON schemas as published by their respective standards communities. The validation support includes customized, BOM-schema variants designed by companies or organizations that may have stricter BOM compliance requirements. +This utility was designed to be an API platform to validate, analyze and edit **Bills-of-Materials (BOMs)**. Initially, it was created to validate **CycloneDX** or **SPDX-formatted** BOMs against versioned JSON schemas (as published by their respective standards communities) or customized schema variants designed by organizations that may have stricter compliance requirements. -The utility has steadily grown to include a rich set of commands, listed below, such as **trim**, **patch** (IETF RFC 6902) and **diff** as well as commands used to create filtered reports using the utility's powerful, SQL-like **query** command capability. +The utility now includes a rich set of commands, listed below, such as **trim**, **patch** (IETF RFC 6902) and **diff** as well as commands used to create filtered reports, in various formats, using the utility's powerful, SQL-like **query** command capability. Supported report commands can easily extract **license**, **license policy**, **vulnerability**, **component**, **service** and other BOM information enabling verification for most [BOM use cases](#cyclonedx-use-cases) as well as custom security and compliance requirements. @@ -18,7 +18,7 @@ The utility supports the following commands: - **[list](#license-list-subcommand)** produce listings or summarized reports of license data contained in a BOM along with license "usage policy" determinations using the policies declared in the `license.json` file. - **[policy](#license-policy-subcommand)** - lists software and data license information and associated license usage policies as defined in the configurable `license.json` file. -- **[query](#query)** produce data listings or custom reports from BOM data using SQL-style query statements (i.e., `--select --from --where `). +- **[query](#query)** retrieves JSON data from BOMs using SQL-style query statements (i.e., `--select --from --where `). The JSON data can be used to create custom listings or reports. - **[resource](#resource)** produce filterable listings or summarized reports of resources, including components and services, from BOM data. @@ -27,7 +27,7 @@ The utility supports the following commands: - **[trim](#trim)** provide the ability to remove specified JSON information from the input JSON BOM document and produce output BOMs with reduced or targeted sets of information. A SQL-like set of parameters allows for fine-grained specification of which fields should be trimmed from which document paths. -- **[validate](#validate)** enables validation of SBOMs against their declared format (e.g., SPDX, CycloneDX) and version (e.g., "2.2", "1.4", etc.) using their JSON schemas. +- **[validate](#validate)** enables validation of SBOMs against their declared format (e.g., SPDX, CycloneDX) and version (e.g., "2.3", "1.5", etc.) using their JSON schemas. - Derivative, **"customized" schemas** can be used for verification using the `--variant` flag (e.g., industry or company-specific schemas). - You can override an BOM's declared BOM version using the `--force` flag (e.g., verify a BOM against a newer specification version). @@ -35,7 +35,7 @@ The utility supports the following commands: **Experimental commands**: -Feedback and helpful commits appreciated on the following commands which will be moved to non-experimental after two point releases: +Feedback and helpful commits appreciated on the following commands which will be promoted after at least two point releases: - **[diff](#diff)** : Shows the delta between two similar BOM versions in JSON (diff) patch format as defined by [IETF RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902/). @@ -48,20 +48,21 @@ Feedback and helpful commits appreciated on the following commands which will be - [Installation](#installation) - [Running](#running) - [Commands](#commands) - - [General information](#general-command-information) - - [Exit codes](#exit-codes): (e.g., `0`: none, `1`: application, `2`: validation) - - [Persistent flags](#persistent-flags) (e.g., `--format`, `--quiet`, `--where`) - - [`license` command](#license) + - [Exit codes](#exit-codes): (e.g., `0`: none, `1`: application, `2`: validation) + - [Persistent flags](#persistent-flags) (e.g., `--format`, `--quiet`, `--where`, etc.) + - [license](#license) - [list](#license-list-subcommand) subcommand: lists all license information found in the BOM - [policy](#license-policy-subcommand) subcommand: lists configurable license usage policies - - [`query` command](#query): extract JSON objects and fields from a BOM using SQL-like queries - - [`resource` command](#resource): list resource information by type (e.g., components, services) - - [`schema` command](#schema): list supported BOM formats, versions, variants - - [`validate` command](#validate): BOM against declared or required schema - - [`vulnerability` command](#vulnerability): lists vulnerability summary information included in the BOM or VEX - - [`diff` command](#diff): *experimental*: shows the delta between two similar BOM versions - - [`trim` command](#diff): *experimental*: remove specified fields from JSON BOM documents and output smaller BOMs that are appropriate sized for different use cases and analysis - - [`completion` command](#completion): generates command-line completion scripts for the utility + - [query](#query): extract JSON objects and fields from a BOM using SQL-like queries + - [resource](#resource): list resource information by type (e.g., components, services) + - [schema](#schema): list supported BOM formats, versions, variants + - [trim](#trim): remove unnecessary fields and data from a BOM + - [validate](#validate): BOM against declared or required schema + - [vulnerability](#vulnerability): lists vulnerability summary information included in the BOM or VEX + - [completion](#completion): generates command-line completion scripts for the utility +- [Experimental commands](#experimental-commands) + - [diff](#diff): compares differences between two similar BOMs + - [patch](#patch): patches BOMs using IETF RFC 6902 records. - [Design considerations](#design-considerations) - [Development](#development) - [Prerequisites](#prerequisites) @@ -913,6 +914,8 @@ For details see the "[Adding SBOM formats, schema versions and variants](#adding If you wish to have the new schema *embedded in the executable*, simply add it to the project's `resources` subdirectory following the format and version-based directory structure. +--- + ### Trim This command is able to "trim" one or more JSON keys (fields) from specified JSON BOM documents effectively "pruning" the JSON document. This functionality helps consumers of large-sized BOMs that need to analyze specific types of data in large BOMs in reducing the BOM data to just what is needed for their use cases or needs. @@ -1127,908 +1130,912 @@ Output BOM results with `properties` removed from all `components`: --- -### Patch - -This command is able to "patch" an existing JSON BOM document using an [IETF RFC6902](https://datatracker.ietf.org/doc/html/rfc6902/#section-4.1) *"JavaScript Object Notation (JSON) Patch"* file. - -The current implementation supports the following "patch" operations: - -- "add", "update", "remove" and "test" +### Validate -At this time the "move" or "copy" operations are not supported. +This command will parse standardized SBOMs and validate it against its declared format and version (e.g., SPDX 2.2, CycloneDX 1.4). Custom variants of standard JSON schemas can be used for validation by supplying the `--variant` name as a flag. Explicit JSON schemas can be specified using the `--force` flag. -Patches work for both simple (i.e., integer, float, boolean and string) values as well as complex values such as JSON objects, maps and arrays. +#### Validate supported schemas -#### Patch supported output formats +Use the [schema](#schema) command to list supported schemas formats, versions and variants. -This command is used to output, using the [`--output-file` flag](#output-flag), a "patched" BOM in JSON format. +Customized JSON schemas can also be permanently configured as named schema "variants" within the utility's configuration file. See [adding schemas](#adding-schemas). -- `json` (default) +#### Validate flags -#### Patch flags +The following flags can be used to improve performance when formatting error output results: -The patch command operates on a JSON BOM input file (see [`--input-file` flag](#input-flag)) as well as an [IETF RFC6902](https://datatracker.ietf.org/doc/html/rfc6902/#section-4.1)-formatted "patch' file and produces a "patched" version of the input JSON BOM as output using the following flags: +##### `--error-limit` flag -##### Patch `--patch-filename` flag +Use the `--error-limit x` (default: `10`) flag to reduce the formatted error result output to the first `x` errors. By default, only the first 10 errors are output with an informational messaging indicating `x/y` errors were shown. -The `--patch-file ` flag is used to provide the relative path to the IETF RFC6902 patch file to applied to the BOM input file. +##### `--error-value` flag -#### Patch examples +Use the `--error-value=true|false` (default: `true`) flag to reduce the formatted error result output by not showing the `value` field which shows detailed information about the failing data in the BOM. -This section contains examples of all supported patch operations (i.e., add, replace, test) including values that are primitives (i.e., `numbers`, `strings`) as well as JSON `objects` and may be indexed JSON `array` elements. +##### `--colorize` flag -- ["add" BOM `serialNumber`](#patch-example-1-add-bom-serialnumber) -- ["add" (update) BOM `version`](#patch-example-2-add-update-bom-version) -- ["add" `supplier` object to `metadata`](#patch-example-3-add-supplier-object-to-metadata-object) -- ["add" `property` objects to `metadata.properties` array](#patch-example-4-add-property-objects-to-metadataproperties-array) -- ["replace" `version` and `timestamp` values](#patch-example-5-replace-bom-version-and-timestamp) -- ["remove" `property` from the `metadata.properties` array](#patch-example-6-remove-property-from-the-metadataproperties-array) -- ["test" if a `property` exists in the `metadata.properties` array](#patch-example-7-test-property-exists-in-the-metadataproperties-array) +Use the `--colorize=true|false` (default: `false`) flag to add/remove color formatting to error result `txt` formatted output. By default, `txt` formatted error output is colorized to help with human readability; for automated use, it can be turned off. -##### Patch example 1: "add" BOM `serialNumber` +#### Validate Examples -This example adds a new top-level key `"serialNumber"` and corresponding value to a CycloneDX JSON BOM file. +##### Example: Validate using inferred format and schema -The original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json) has no serial number: +Validating the "juice shop" SBOM (CycloneDX 1.2) example provided in this repository. -```json -{ - "bomFormat": "CycloneDX", - "specVersion": "1.5", - "version": 1, - "metadata": { - ... - } -} +```bash +./sbom-utility validate -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json ``` -IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-add-serial-number.json](test/patch/cdx-patch-example-add-serial-number.json): - -```json -[ - { "op": "add", "path": "/serialNumber", "value": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9" } -] +```bash +[INFO] Loading (embedded) default schema config file: `config.json`... +[INFO] Loading (embedded) default license policy file: `license.json`... +[INFO] Attempting to load and unmarshal data from: `examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json`... +[INFO] Successfully unmarshalled data from: `examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json` +[INFO] Determining file's BOM format and version... +[INFO] Determined BOM format, version (variant): `CycloneDX`, `1.2` (latest) +[INFO] Matching BOM schema (for validation): schema/cyclonedx/1.2/bom-1.2.schema.json +[INFO] Loading schema `schema/cyclonedx/1.2/bom-1.2.schema.json`... +[INFO] Schema `schema/cyclonedx/1.2/bom-1.2.schema.json` loaded. +[INFO] Validating `examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json`... +[INFO] BOM valid against JSON schema: `true` ``` -Invoke the patch command as follows: +You can also verify the [exit code](#exit-codes) from the validate command: ```bash -./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-add-serial-number.json -q +echo $? ``` -Patched JSON BOM output file: - -```json -{ - "bomFormat": "CycloneDX", - "specVersion": "1.5", - "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9", - "version": 1, - "metadata": { - ... - } -} +```bash +0 // no error (valid) ``` -##### Patch example 2: "add" (update) BOM `version` - -This example shows how the patch's "add" operation can be used to update existing values which is the specified behavior of RFC6902. +#### Example: Validate using "custom" schema variants -Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json) with `version` equal to `1`: +The validation command will use the declared format and version found within the SBOM JSON file itself to lookup the default (latest) matching schema version (as declared in`config.json`; however, if variants of that same schema (same format and version) are declared, they can be requested via the `--variant` command line flag: -```json -{ - "bomFormat": "CycloneDX", - "specVersion": "1.5", - "version": 1, - "metadata": { - ... - } -} +```bash +./sbom-utility validate -i test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json --variant custom ``` -IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-add-serial-number.json](test/patch/cdx-patch-example-add-serial-number.json): +If you run the sample command above, you would see several "custom" schema errors resulting in an invalid SBOM determination (i.e., `exit status 2`): -```json -[ - { "op": "add", "path": "/version", "value": 2 } -] +```text +[INFO] Loading (embedded) default schema config file: `config.json`... +[INFO] Loading (embedded) default license policy file: `license.json`... +[INFO] Attempting to load and unmarshal data from: `test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json`... +[INFO] Successfully unmarshalled data from: `test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json` +[INFO] Determining file's BOM format and version... +[INFO] Determined BOM format, version (variant): `CycloneDX`, `1.4` custom +[INFO] Matching BOM schema (for validation): schema/test/bom-1.4-custom.schema.json +[INFO] Loading schema `schema/test/bom-1.4-custom.schema.json`... +[INFO] Schema `schema/test/bom-1.4-custom.schema.json` loaded. +[INFO] Validating `test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json`... +[INFO] BOM valid against JSON schema: `false` +[INFO] (3) schema errors detected. +[INFO] Formatting error results (`txt` format)... +1. { + "type": "contains", + "field": "metadata.properties", + "context": "(root).metadata.properties", + "description": "At least one of the items must match", + "value": [ + { + "name": "urn:example.com:disclaimer", + "value": "This SBOM is current as of the date it was generated." + }, + { + "name": "urn:example.com:classification", + "value": "This SBOM is Confidential Information. Do not distribute." + } + ] + } +2. { + "type": "const", + "field": "metadata.properties.0.value", + "context": "(root).metadata.properties.0.value", + "description": "metadata.properties.0.value does not match: \"This SBOM is current as of the date it was generated and is subject to change.\"", + "value": "This SBOM is current as of the date it was generated." + } +3. { + "type": "number_all_of", + "field": "metadata.properties", + "context": "(root).metadata.properties", + "description": "Must validate all the schemas (allOf)", + "value": [ + { + "name": "urn:example.com:disclaimer", + "value": "This SBOM is current as of the date it was generated." + }, + { + "name": "urn:example.com:classification", + "value": "This SBOM is Confidential Information. Do not distribute." + } + ] + } +[ERROR] invalid SBOM: schema errors found (test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json) +[INFO] document `test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json`: valid=[false] ``` -Invoke the patch command as follows: +confirming the exit code: ```bash -./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-add-update-version.json -q +echo $? ``` -The patched, output JSON BOM file which has the changed `version` value of `2`: - -```json -{ - "bomFormat": "CycloneDX", - "specVersion": "1.5", - "version": 2, - "metadata": { - ... - } -} +```bash +2 // SBOM error ``` -##### Patch example 3: "add" `supplier` object to `metadata` object +##### Why validation failed -This example shows how the patch's "add" operation can be used to add a JSON object to an existing object. +The output shows a first schema error indicating the failing JSON object; in this case, -Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json): +- the CycloneDX `metadata.properties` field, which is a list of `property` objects. +- Found that a property with a `name` field with the value `"urn:example.com:disclaimer"` had an incorrect `value`. + - the `value` field SHOULD have had a constant value of `"This SBOM is current as of the date it was generated and is subject to change."` (as was required by the custom schema's regex). + - However, it was found to have only a partial match of `"This SBOM is current as of the date it was generated."`. -```json -{ - "bomFormat": "CycloneDX", - "specVersion": "1.5", - "version": 1, - "metadata": { - "timestamp": "2023-10-12T19:07:00Z", - "properties": [ - ... - ] - } -} +##### Details of the schema error + +Use the `--debug` or `-d` flag to see all schema error details: + +```bash +./sbom-utility validate -i test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json --variant custom -d ``` -Apply the following IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-add-metadata-supplier.json](test/patch/cdx-patch-example-add-metadata-supplier.json): +The details include the full context of the failing `metadata.properties` object which also includes a `"urn:example.com:classification"` property: -```json -[ - { "op": "add", "path": "/metadata/supplier", "value": { - "name": "Example Co. Distribution Dept.", - "url": [ - "https://example.com/software/" - ] +```bash +3. { + "type": "number_all_of", + "field": "metadata.properties", + "context": "(root).metadata.properties", + "description": "Must validate all the schemas (allOf)", + "value": [ + { + "name": "urn:example.com:disclaimer", + "value": "This SBOM is current as of the date it was generated." + }, + { + "name": "urn:example.com:classification", + "value": "This SBOM is Confidential Information. Do not distribute." + } + ] } - } -] ``` -Invoke the patch command as follows: +#### Example: Validate using "JSON" format + +The JSON format will provide an `array` of schema error results that can be post-processed as part of validation toolchain. ```bash -./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-add-metadata-supplier.json -q +./sbom-utility validate -i test/validation/cdx-1-4-validate-err-components-unique-items-1.json --format json --quiet ``` -The patched BOM has the `supplier` object added to the `metadata`: - ```json -{ - "bomFormat": "CycloneDX", - "specVersion": "1.5", - "version": 1, - "metadata": { - "timestamp": "2023-10-12T19:07:00Z", - "supplier": { - "name": "Example Co. Distribution Dept.", - "url": [ - "https://example.com/software/" - ] - }, - "properties": [ - ... - ] +[ + { + "type": "unique", + "field": "components", + "context": "(root).components", + "description": "array items[1,2] must be unique", + "value": { + "type": "array", + "index": 1, + "item": { + "bom-ref": "pkg:npm/body-parser@1.19.0", + "description": "Node.js body parsing middleware", + "hashes": [ + { + "alg": "SHA-1", + "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "body-parser", + "purl": "pkg:npm/body-parser@1.19.0", + "type": "library", + "version": "1.19.0" + } + } + }, + { + "type": "unique", + "field": "components", + "context": "(root).components", + "description": "array items[2,4] must be unique", + "value": { + "type": "array", + "index": 2, + "item": { + "bom-ref": "pkg:npm/body-parser@1.19.0", + "description": "Node.js body parsing middleware", + "hashes": [ + { + "alg": "SHA-1", + "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "body-parser", + "purl": "pkg:npm/body-parser@1.19.0", + "type": "library", + "version": "1.19.0" + } + } } -} +] ``` -##### Patch example 4: "add" `property` objects to `metadata.properties` array +##### Reducing output size using `error-value=false` flag -This example shows how the patch's "add" operation can be used to add `property` objects to an existing `properties` array. +In many cases, BOMs may have many errors and having the `value` information details included can be too verbose and lead to large output files to inspect. In those cases, simply set the `error-value` flag to `false`. -Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json): +Rerunning the same command with this flag set to false yields a reduced set of information. -```json -{ - "bomFormat": "CycloneDX", - "specVersion": "1.5", - "version": 1, - "metadata": { - "timestamp": "2023-10-12T19:07:00Z", - "properties": [ - { - "name": "Property 1", - "value": "Value 1" - }, - { - "name": "Property 2", - "value": "Value 2" - } - ] - } -} +```bash +./sbom-utility validate -i test/validation/cdx-1-4-validate-err-components-unique-items-1.json --format json --error-value=false --quiet ``` -Apply the following IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-add-metadata-properties.json](test/patch/cdx-patch-example-add-metadata-properties.json): - ```json [ - { "op": "add", "path": "/metadata/properties/-", "value": { "name": "foo", "value": "bar" } }, - { "op": "add", "path": "/metadata/properties/1", "value": { "name": "rush", "value": "yyz" } } + { + "type": "unique", + "field": "components", + "context": "(root).components", + "description": "array items[1,2] must be unique" + }, + { + "type": "unique", + "field": "components", + "context": "(root).components", + "description": "array items[2,4] must be unique" + } ] ``` -Note that the first patch record uses the `-` (dash) to indicate "insert at end" whereas the second patch record has the zero-based array index `1`. +--- -Invoke the patch command as follows: +### Vulnerability -```bash -./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-add-metadata-properties.json -q -``` +This command will extract basic vulnerability report data from an SBOM that has a "vulnerabilities" list or from a standalone VEX in CycloneDX format. It includes the ability to filter reports data by applying regex to any of the named column data. -The patched, output BOM has the two new properties at the specified indices: +#### Vulnerability supported output formats -```json -{ - "bomFormat": "CycloneDX", - "specVersion": "1.5", - "version": 1, - "metadata": { - "timestamp": "2023-10-12T19:07:00Z", - "properties": [ - { - "name": "Property 1", - "value": "Value 1" - }, - { - "name": "rush", - "value": "yyz" - }, - { - "name": "Property 2", - "value": "Value 2" - }, - { - "name": "foo", - "value": "bar" - } - ] - } -} -``` +Use the `--format` flag on the to choose one of the supported output formats: -##### Patch example 5: "replace" BOM `version` and `timestamp` +- txt (default), csv, md -This example shows how the patch's "replace" operation can be used to update the BOM document's `version` and `timestamp` values. +#### Vulnerability result sorting -Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json): +- `txt`, `csv` and `md` formatted results are sorted by vulnerability `id` (descending) then by `created` date (descending). +- `json` results are not sorted -```json -{ - "bomFormat": "CycloneDX", - "specVersion": "1.5", - "version": 1, - "metadata": { - "timestamp": "2023-10-12T19:07:00Z", - "properties": [ - ... - ] - } -} -``` +#### Vulnerability Examples -Apply the following IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-replace-version-timestamp.json](test/patch/cdx-patch-example-replace-version-timestamp.json): +##### Example: Vulnerability list -```json -[ - { "op": "replace", "path": "/version", "value": 2 }, - { "op": "replace", "path": "/metadata/timestamp", "value": "2024-01-24T22:50:18+00:00" } -] -``` +The `list` subcommand provides a complete view of most top-level, vulnerability fields. -Invoke the patch command as follows: +```bash +./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json --quiet +``` ```bash -./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-replace-version-timestamp.json -q +id bom-ref cwe-ids cvss-severity source-name source-url published updated created rejected analysis-state analysis-justification description +-- ------- ------- ------------- ----------- ---------- --------- ------- ------- -------- -------------- ---------------------- ----------- +CVE-2023-42004 502 CVSSv31: 7.5 (high) NVD https://nvd.nist.gov/vuln/detail/CVE-2023-42004 2023-10-02 2023-10-02 2023-10-02 UNDEFINED UNDEFINED In FasterXML jackson-databind before 2.13.4, resource exhaustion can occur because of a lack of a check in BeanDeserializer._deserializeFromArray to prevent use of deeply nested arrays. An application is vulnerable only with certain customized choices for deserialization. +CVE-2023-42003 502 CVSSv31: 7.5 (high) NVD https://nvd.nist.gov/vuln/detail/CVE-2023-42003 2023-10-02 2023-10-02 2023-10-02 UNDEFINED UNDEFINED In FasterXML jackson-databind before 2.14.0-rc1, resource exhaustion can occur because of a lack of a check in primitive value deserializers to avoid deep wrapper array nesting, when the UNWRAP_SINGLE_VALUE_ARRAYS feature is enabled. Additional fix version in 2.13.4.1 and 2.12.17.1 +CVE-2020-25649 611 CVSSv31: 7.5 (high), CVSSv31: 8.2 (high), CVSSv31: 0 (none) NVD https://nvd.nist.gov/vuln/detail/CVE-2020-25649 2020-12-03 2023-02-02 2020-12-03 not_affected code_not_reachable com.fasterxml.jackson.core:jackson-databind is a library which contains the general-purpose data-binding functionality and tree-model for Jackson Data Processor. Affected versions of this package are vulnerable to XML External Entity (XXE) Injection. A flaw was found in FasterXML Jackson Databind, where it does not have entity expansion secured properly in the DOMDeserializer class. The highest threat from this vulnerability is data integrity. ``` -The patched, output BOM has both an updated `version` and `timestamp`: +###### Example: Vulnerability list summary -```json -{ - "bomFormat": "CycloneDX", - "specVersion": "1.5", - "version": 2, - "metadata": { - "timestamp": "2024-01-24T22:50:18+00:00", - "properties": [ - ... - } -} +This example shows the default text output from using the `--summary` flag: + +```bash +./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json --quiet --summary ``` -##### Patch example 6: "remove" `property` from the `metadata.properties` array +```bash +id cvss-severity source-name published description +-- ------------- ----------- --------- ----------- +CVE-2023-42004 CVSSv31: 7.5 (high) NVD 2023-10-02 In FasterXML jackson-databind before 2.13.4, resource exhaustion can occur because of a lack of a check in BeanDeserializer._deserializeFromArray to prevent use of deeply nested arrays. An application is vulnerable only with certain customized choices for deserialization. +CVE-2023-42003 CVSSv31: 7.5 (high) NVD 2023-10-02 In FasterXML jackson-databind before 2.14.0-rc1, resource exhaustion can occur because of a lack of a check in primitive value deserializers to avoid deep wrapper array nesting, when the UNWRAP_SINGLE_VALUE_ARRAYS feature is enabled. Additional fix version in 2.13.4.1 and 2.12.17.1 +CVE-2020-25649 CVSSv31: 7.5 (high) NVD 2020-12-03 com.fasterxml.jackson.core:jackson-databind is a library which contains the general-purpose data-binding functionality and tree-model for Jackson Data Processor. Affected versions of this package are vulnerable to XML External Entity (XXE) Injection. A flaw was found in FasterXML Jackson Databind, where it does not have entity expansion secured properly in the DOMDeserializer class. The highest threat from this vulnerability is data integrity. +``` -This example shows how the patch's "remove" operation can be used to remove a `property` object from the `metadata.properties` array using an index. +##### Example: Vulnerability list with `--where` filter with `description` key -Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json): +```bash +./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json --quiet --where description=XXE +``` -```json -{ - "bomFormat": "CycloneDX", - "specVersion": "1.5", - "version": 1, - "metadata": { - "timestamp": "2023-10-12T19:07:00Z", - "properties": [ - { - "name": "Property 1", - "value": "Value 1" - }, - { - "name": "Property 2", - "value": "Value 2" - } - ] - } -} +```bash +id bom-ref cwe-ids cvss-severity source-name source-url published updated created rejected analysis-state analysis-justification description +-- ------- ------- ------------- ----------- ---------- --------- ------- ------- -------- -------------- ---------------------- ----------- +CVE-2020-25649 611 CVSSv31: 7.5 (high), CVSSv31: 8.2 (high), CVSSv31: 0 (none) NVD https://nvd.nist.gov/vuln/detail/CVE-2020-25649 2020-12-03 2023-02-02 2020-12-03 not_affected code_not_reachable com.fasterxml.jackson.core:jackson-databind is a library which contains the general-purpose data-binding functionality and tree-model for Jackson Data Processor. Affected versions of this package are vulnerable to XML External Entity (XXE) Injection. A flaw was found in FasterXML Jackson Databind, where it does not have entity expansion secured properly in the DOMDeserializer class. The highest threat from this vulnerability is data integrity. ``` -Apply the following IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-remove-metadata-property.json](test/patch/cdx-patch-example-remove-metadata-property.json): +##### Example: Vulnerability list with `--where` filter with `analysis-state` key -```json -[ - { "op": "remove", "path": "/metadata/properties/1" } -] +```bash +./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json --quiet --where analysis-state=not_affected ``` -Invoke the patch command as follows: - ```bash -./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-remove-metadata-property.json -q +id bom-ref cwe-ids cvss-severity source-name source-url published updated created rejected analysis-state analysis-justification description +-- ------- ------- ------------- ----------- ---------- --------- ------- ------- -------- -------------- ---------------------- ----------- +CVE-2020-25649 611 CVSSv31: 7.5 (high), CVSSv31: 8.2 (high), CVSSv31: 0 (none) NVD https://nvd.nist.gov/vuln/detail/CVE-2020-25649 2020-12-03 2023-02-02 2020-12-03 not_affected code_not_reachable com.fasterxml.jackson.core:jackson-databind is a library which contains the general-purpose data-binding functionality and tree-model for Jackson Data Processor. Affected versions of this package are vulnerable to XML External Entity (XXE) Injection. A flaw was found in FasterXML Jackson Databind, where it does not have entity expansion secured properly in the DOMDeserializer class. The highest threat from this vulnerability is data integrity. ``` -The `property` at index `1` of the `metadata.properties` array has been removed: +--- -```json -{ - "bomFormat": "CycloneDX", - "specVersion": "1.5", - "version": 1, - "metadata": { - "timestamp": "2023-10-12T19:07:00Z", - "properties": [ - { - "name": "Property 1", - "value": "Value 1" - } - ] - } -} +#### Completion + +This command will generate command-line completion scripts, for the this utility, customized for various supported shells. + +The completion command can be invoked as follows: + +```bash +./sbom_utility completion [shell] ``` -##### Patch example 7: "test" `property` exists in the `metadata.properties` array +where valid values for `shell` are: -This example shows how the patch records's can "test" for values or objects in a BOM. The utility will confirm "success" (using an `[INFO]` log message); otherwise, the utility will exit and return an error and generate an `[ERROR]` log message. +- bash +- fish +- powershell +- zsh -Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json): +--- -```json -{ - "bomFormat": "CycloneDX", - "specVersion": "1.5", - "version": 1, - "metadata": { - "timestamp": "2023-10-12T19:07:00Z", - "properties": [ - { - "name": "Property 1", - "value": "Value 1" - }, - { - "name": "Property 2", - "value": "Value 2" - } - ] - } -} -``` +### Help -Apply the following IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-test-metadata-property.json](test/patch/cdx-patch-example-test-metadata-property.json): +The utility supports the `help` command for the root command as well as any supported commands + +For example, to list top-level (root command) help which lists the supported "Available Commands": -```json -[ - { "op": "test", "path": "/metadata/properties/1", "value": - { - "name": "Property 2", - "value": "Value 2" - } - } -] +```bash +./sbom-utility help ``` -Invoke the patch command as follows: +A specific command-level help listing is also available. For example, you can access the help for the `validate` command: ```bash -./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-test-metadata-property.json -q +./sbom-utility help validate ``` -An informational (i.e., `[INFO]`) message is logged with `success` since the property object was found in the input BOM: +--- -```json -[INFO] IETF RFC6902 test operation success. test record: { - "op": "test", - "path": "/metadata/properties/1", - "value": { - "name": "Property 2", - "value": "Value 2" - } -} -``` +## Experimental Commands -If instead, we [tested for a different property](test/patch/cdx-patch-example-test-metadata-property-err.json) object: +This section contains *experimental* commands that will be promoted once vetted by the community over two or more point releases. -```json -[ - { "op": "test", "path": "/metadata/properties/1", "value": - { - "name": "Property 3", - "value": "Value 3" - } - } -] -``` +### Diff -an error (i.e., `[ERROR]`) would be returned from the utility: +This *experimental* command will compare two *similar* BOMs and return the delta (or "diff") in JSON (diff-patch format) or text. This functionality is based upon code ancestral to that used to report file diffs between `git commit`s. -```json -[ERROR] IETF RFC6902 test operation error. test record: { - "op": "test", - "path": "/metadata/properties/1", - "value": { - "name": "Property 3", - "value": "Value 3" - } -} +##### Notes + +- This command is undergoing analysis and tests which are exposing some underlying issues around "moved" objects in dependent diff-patch packages that may not be fixable and have no alternatives. + - *Specifically, the means by which "moved" objects are assigned "similarity" scores appears flawed in the case of JSON.* + - *Additionally, some of the underlying code relies upon Go maps which do not preserve key ordering.* + +#### Diff supported output formats + +Use the `--format` flag on the to choose one of the supported output formats: + +- txt (default), json + +#### Diff Examples + +##### Example: Add, delete and modify + +```bash +./sbom-utility diff -i test/diff/json-array-order-change-with-add-and-delete-base.json -r test/diff/json-array-order-change-with-add-and-delete-delta.json --quiet --format txt --colorize=true +``` + +```bash + { + "licenses": [ + 0: { + "license": { +- "id": "Apache-1.0" ++ "id": "GPL-2.0" + } + }, +-+ 2=>1: { +-+ "license": { +-+ "id": "GPL-3.0-only" +-+ } +-+ }, + 2: { + "license": { + "id": "GPL-3.0-only" + } + }, + 3: { + "license": { + "id": "MIT" + } + } + ] + } ``` --- -### Validate +### Patch -This command will parse standardized SBOMs and validate it against its declared format and version (e.g., SPDX 2.2, CycloneDX 1.4). Custom variants of standard JSON schemas can be used for validation by supplying the `--variant` name as a flag. Explicit JSON schemas can be specified using the `--force` flag. +This *experimental* command is able to "patch" an existing JSON BOM document using an [IETF RFC6902](https://datatracker.ietf.org/doc/html/rfc6902/#section-4.1) *"JavaScript Object Notation (JSON) Patch"* file. -#### Validate supported schemas +The current implementation supports the following "patch" operations: -Use the [schema](#schema) command to list supported schemas formats, versions and variants. +- "add", "update", "remove" and "test" -Customized JSON schemas can also be permanently configured as named schema "variants" within the utility's configuration file. See [adding schemas](#adding-schemas). +At this time the "move" or "copy" operations are not supported. -#### Validate flags +Patches work for both simple (i.e., integer, float, boolean and string) values as well as complex values such as JSON objects, maps and arrays. -The following flags can be used to improve performance when formatting error output results: +#### Patch supported output formats -##### `--error-limit` flag +This command is used to output, using the [`--output-file` flag](#output-flag), a "patched" BOM in JSON format. -Use the `--error-limit x` (default: `10`) flag to reduce the formatted error result output to the first `x` errors. By default, only the first 10 errors are output with an informational messaging indicating `x/y` errors were shown. +- `json` (default) -##### `--error-value` flag +#### Patch flags -Use the `--error-value=true|false` (default: `true`) flag to reduce the formatted error result output by not showing the `value` field which shows detailed information about the failing data in the BOM. +The patch command operates on a JSON BOM input file (see [`--input-file` flag](#input-flag)) as well as an [IETF RFC6902](https://datatracker.ietf.org/doc/html/rfc6902/#section-4.1)-formatted "patch' file and produces a "patched" version of the input JSON BOM as output using the following flags: -##### `--colorize` flag +##### Patch `--patch-filename` flag -Use the `--colorize=true|false` (default: `false`) flag to add/remove color formatting to error result `txt` formatted output. By default, `txt` formatted error output is colorized to help with human readability; for automated use, it can be turned off. +The `--patch-file ` flag is used to provide the relative path to the IETF RFC6902 patch file to applied to the BOM input file. -#### Validate Examples +#### Patch examples -##### Example: Validate using inferred format and schema +This section contains examples of all supported patch operations (i.e., add, replace, test) including values that are primitives (i.e., `numbers`, `strings`) as well as JSON `objects` and may be indexed JSON `array` elements. -Validating the "juice shop" SBOM (CycloneDX 1.2) example provided in this repository. +- ["add" BOM `serialNumber`](#patch-example-1-add-bom-serialnumber) +- ["add" (update) BOM `version`](#patch-example-2-add-update-bom-version) +- ["add" `supplier` object to `metadata`](#patch-example-3-add-supplier-object-to-metadata-object) +- ["add" `property` objects to `metadata.properties` array](#patch-example-4-add-property-objects-to-metadataproperties-array) +- ["replace" `version` and `timestamp` values](#patch-example-5-replace-bom-version-and-timestamp) +- ["remove" `property` from the `metadata.properties` array](#patch-example-6-remove-property-from-the-metadataproperties-array) +- ["test" if a `property` exists in the `metadata.properties` array](#patch-example-7-test-property-exists-in-the-metadataproperties-array) -```bash -./sbom-utility validate -i examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json -``` +##### Patch example 1: "add" BOM `serialNumber` -```bash -[INFO] Loading (embedded) default schema config file: `config.json`... -[INFO] Loading (embedded) default license policy file: `license.json`... -[INFO] Attempting to load and unmarshal data from: `examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json`... -[INFO] Successfully unmarshalled data from: `examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json` -[INFO] Determining file's BOM format and version... -[INFO] Determined BOM format, version (variant): `CycloneDX`, `1.2` (latest) -[INFO] Matching BOM schema (for validation): schema/cyclonedx/1.2/bom-1.2.schema.json -[INFO] Loading schema `schema/cyclonedx/1.2/bom-1.2.schema.json`... -[INFO] Schema `schema/cyclonedx/1.2/bom-1.2.schema.json` loaded. -[INFO] Validating `examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json`... -[INFO] BOM valid against JSON schema: `true` -``` +This example adds a new top-level key `"serialNumber"` and corresponding value to a CycloneDX JSON BOM file. -You can also verify the [exit code](#exit-codes) from the validate command: +The original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json) has no serial number: -```bash -echo $? +```json +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "version": 1, + "metadata": { + ... + } +} ``` -```bash -0 // no error (valid) -``` +IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-add-serial-number.json](test/patch/cdx-patch-example-add-serial-number.json): -#### Example: Validate using "custom" schema variants +```json +[ + { "op": "add", "path": "/serialNumber", "value": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9" } +] +``` -The validation command will use the declared format and version found within the SBOM JSON file itself to lookup the default (latest) matching schema version (as declared in`config.json`; however, if variants of that same schema (same format and version) are declared, they can be requested via the `--variant` command line flag: +Invoke the patch command as follows: ```bash -./sbom-utility validate -i test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json --variant custom +./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-add-serial-number.json -q ``` -If you run the sample command above, you would see several "custom" schema errors resulting in an invalid SBOM determination (i.e., `exit status 2`): +Patched JSON BOM output file: -```text -[INFO] Loading (embedded) default schema config file: `config.json`... -[INFO] Loading (embedded) default license policy file: `license.json`... -[INFO] Attempting to load and unmarshal data from: `test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json`... -[INFO] Successfully unmarshalled data from: `test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json` -[INFO] Determining file's BOM format and version... -[INFO] Determined BOM format, version (variant): `CycloneDX`, `1.4` custom -[INFO] Matching BOM schema (for validation): schema/test/bom-1.4-custom.schema.json -[INFO] Loading schema `schema/test/bom-1.4-custom.schema.json`... -[INFO] Schema `schema/test/bom-1.4-custom.schema.json` loaded. -[INFO] Validating `test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json`... -[INFO] BOM valid against JSON schema: `false` -[INFO] (3) schema errors detected. -[INFO] Formatting error results (`txt` format)... -1. { - "type": "contains", - "field": "metadata.properties", - "context": "(root).metadata.properties", - "description": "At least one of the items must match", - "value": [ - { - "name": "urn:example.com:disclaimer", - "value": "This SBOM is current as of the date it was generated." - }, - { - "name": "urn:example.com:classification", - "value": "This SBOM is Confidential Information. Do not distribute." - } - ] - } -2. { - "type": "const", - "field": "metadata.properties.0.value", - "context": "(root).metadata.properties.0.value", - "description": "metadata.properties.0.value does not match: \"This SBOM is current as of the date it was generated and is subject to change.\"", - "value": "This SBOM is current as of the date it was generated." - } -3. { - "type": "number_all_of", - "field": "metadata.properties", - "context": "(root).metadata.properties", - "description": "Must validate all the schemas (allOf)", - "value": [ - { - "name": "urn:example.com:disclaimer", - "value": "This SBOM is current as of the date it was generated." - }, - { - "name": "urn:example.com:classification", - "value": "This SBOM is Confidential Information. Do not distribute." - } - ] +```json +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "serialNumber": "urn:uuid:1a2b3c4d-1234-abcd-9876-a3b4c5d6e7f9", + "version": 1, + "metadata": { + ... } -[ERROR] invalid SBOM: schema errors found (test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json) -[INFO] document `test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json`: valid=[false] +} +``` + +##### Patch example 2: "add" (update) BOM `version` + +This example shows how the patch's "add" operation can be used to update existing values which is the specified behavior of RFC6902. + +Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json) with `version` equal to `1`: + +```json +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "version": 1, + "metadata": { + ... + } +} ``` -confirming the exit code: +IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-add-serial-number.json](test/patch/cdx-patch-example-add-serial-number.json): -```bash -echo $? +```json +[ + { "op": "add", "path": "/version", "value": 2 } +] ``` +Invoke the patch command as follows: + ```bash -2 // SBOM error +./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-add-update-version.json -q ``` -##### Why validation failed +The patched, output JSON BOM file which has the changed `version` value of `2`: -The output shows a first schema error indicating the failing JSON object; in this case, +```json +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "version": 2, + "metadata": { + ... + } +} +``` -- the CycloneDX `metadata.properties` field, which is a list of `property` objects. -- Found that a property with a `name` field with the value `"urn:example.com:disclaimer"` had an incorrect `value`. - - the `value` field SHOULD have had a constant value of `"This SBOM is current as of the date it was generated and is subject to change."` (as was required by the custom schema's regex). - - However, it was found to have only a partial match of `"This SBOM is current as of the date it was generated."`. +##### Patch example 3: "add" `supplier` object to `metadata` object -##### Details of the schema error +This example shows how the patch's "add" operation can be used to add a JSON object to an existing object. -Use the `--debug` or `-d` flag to see all schema error details: +Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json): -```bash -./sbom-utility validate -i test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json --variant custom -d +```json +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "version": 1, + "metadata": { + "timestamp": "2023-10-12T19:07:00Z", + "properties": [ + ... + ] + } +} ``` -The details include the full context of the failing `metadata.properties` object which also includes a `"urn:example.com:classification"` property: +Apply the following IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-add-metadata-supplier.json](test/patch/cdx-patch-example-add-metadata-supplier.json): -```bash -3. { - "type": "number_all_of", - "field": "metadata.properties", - "context": "(root).metadata.properties", - "description": "Must validate all the schemas (allOf)", - "value": [ - { - "name": "urn:example.com:disclaimer", - "value": "This SBOM is current as of the date it was generated." - }, - { - "name": "urn:example.com:classification", - "value": "This SBOM is Confidential Information. Do not distribute." - } - ] +```json +[ + { "op": "add", "path": "/metadata/supplier", "value": { + "name": "Example Co. Distribution Dept.", + "url": [ + "https://example.com/software/" + ] } + } +] ``` -#### Example: Validate using "JSON" format - -The JSON format will provide an `array` of schema error results that can be post-processed as part of validation toolchain. +Invoke the patch command as follows: ```bash -./sbom-utility validate -i test/validation/cdx-1-4-validate-err-components-unique-items-1.json --format json --quiet +./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-add-metadata-supplier.json -q ``` +The patched BOM has the `supplier` object added to the `metadata`: + ```json -[ - { - "type": "unique", - "field": "components", - "context": "(root).components", - "description": "array items[1,2] must be unique", - "value": { - "type": "array", - "index": 1, - "item": { - "bom-ref": "pkg:npm/body-parser@1.19.0", - "description": "Node.js body parsing middleware", - "hashes": [ - { - "alg": "SHA-1", - "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - } - ], - "licenses": [ - { - "license": { - "id": "MIT" - } - } - ], - "name": "body-parser", - "purl": "pkg:npm/body-parser@1.19.0", - "type": "library", - "version": "1.19.0" - } - } - }, - { - "type": "unique", - "field": "components", - "context": "(root).components", - "description": "array items[2,4] must be unique", - "value": { - "type": "array", - "index": 2, - "item": { - "bom-ref": "pkg:npm/body-parser@1.19.0", - "description": "Node.js body parsing middleware", - "hashes": [ - { - "alg": "SHA-1", - "content": "96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - } - ], - "licenses": [ - { - "license": { - "id": "MIT" - } - } - ], - "name": "body-parser", - "purl": "pkg:npm/body-parser@1.19.0", - "type": "library", - "version": "1.19.0" - } - } +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "version": 1, + "metadata": { + "timestamp": "2023-10-12T19:07:00Z", + "supplier": { + "name": "Example Co. Distribution Dept.", + "url": [ + "https://example.com/software/" + ] + }, + "properties": [ + ... + ] } -] +} ``` -##### Reducing output size using `error-value=false` flag +##### Patch example 4: "add" `property` objects to `metadata.properties` array -In many cases, BOMs may have many errors and having the `value` information details included can be too verbose and lead to large output files to inspect. In those cases, simply set the `error-value` flag to `false`. +This example shows how the patch's "add" operation can be used to add `property` objects to an existing `properties` array. -Rerunning the same command with this flag set to false yields a reduced set of information. +Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json): -```bash -./sbom-utility validate -i test/validation/cdx-1-4-validate-err-components-unique-items-1.json --format json --error-value=false --quiet +```json +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "version": 1, + "metadata": { + "timestamp": "2023-10-12T19:07:00Z", + "properties": [ + { + "name": "Property 1", + "value": "Value 1" + }, + { + "name": "Property 2", + "value": "Value 2" + } + ] + } +} ``` +Apply the following IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-add-metadata-properties.json](test/patch/cdx-patch-example-add-metadata-properties.json): + ```json [ - { - "type": "unique", - "field": "components", - "context": "(root).components", - "description": "array items[1,2] must be unique" - }, - { - "type": "unique", - "field": "components", - "context": "(root).components", - "description": "array items[2,4] must be unique" - } + { "op": "add", "path": "/metadata/properties/-", "value": { "name": "foo", "value": "bar" } }, + { "op": "add", "path": "/metadata/properties/1", "value": { "name": "rush", "value": "yyz" } } ] ``` ---- - -### Vulnerability - -This command will extract basic vulnerability report data from an SBOM that has a "vulnerabilities" list or from a standalone VEX in CycloneDX format. It includes the ability to filter reports data by applying regex to any of the named column data. - -#### Vulnerability supported output formats - -Use the `--format` flag on the to choose one of the supported output formats: +Note that the first patch record uses the `-` (dash) to indicate "insert at end" whereas the second patch record has the zero-based array index `1`. -- txt (default), csv, md +Invoke the patch command as follows: -#### Vulnerability result sorting +```bash +./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-add-metadata-properties.json -q +``` -- `txt`, `csv` and `md` formatted results are sorted by vulnerability `id` (descending) then by `created` date (descending). -- `json` results are not sorted +The patched, output BOM has the two new properties at the specified indices: -#### Vulnerability Examples +```json +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "version": 1, + "metadata": { + "timestamp": "2023-10-12T19:07:00Z", + "properties": [ + { + "name": "Property 1", + "value": "Value 1" + }, + { + "name": "rush", + "value": "yyz" + }, + { + "name": "Property 2", + "value": "Value 2" + }, + { + "name": "foo", + "value": "bar" + } + ] + } +} +``` -##### Example: Vulnerability list +##### Patch example 5: "replace" BOM `version` and `timestamp` -The `list` subcommand provides a complete view of most top-level, vulnerability fields. +This example shows how the patch's "replace" operation can be used to update the BOM document's `version` and `timestamp` values. -```bash -./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json --quiet -``` +Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json): -```bash -id bom-ref cwe-ids cvss-severity source-name source-url published updated created rejected analysis-state analysis-justification description --- ------- ------- ------------- ----------- ---------- --------- ------- ------- -------- -------------- ---------------------- ----------- -CVE-2023-42004 502 CVSSv31: 7.5 (high) NVD https://nvd.nist.gov/vuln/detail/CVE-2023-42004 2023-10-02 2023-10-02 2023-10-02 UNDEFINED UNDEFINED In FasterXML jackson-databind before 2.13.4, resource exhaustion can occur because of a lack of a check in BeanDeserializer._deserializeFromArray to prevent use of deeply nested arrays. An application is vulnerable only with certain customized choices for deserialization. -CVE-2023-42003 502 CVSSv31: 7.5 (high) NVD https://nvd.nist.gov/vuln/detail/CVE-2023-42003 2023-10-02 2023-10-02 2023-10-02 UNDEFINED UNDEFINED In FasterXML jackson-databind before 2.14.0-rc1, resource exhaustion can occur because of a lack of a check in primitive value deserializers to avoid deep wrapper array nesting, when the UNWRAP_SINGLE_VALUE_ARRAYS feature is enabled. Additional fix version in 2.13.4.1 and 2.12.17.1 -CVE-2020-25649 611 CVSSv31: 7.5 (high), CVSSv31: 8.2 (high), CVSSv31: 0 (none) NVD https://nvd.nist.gov/vuln/detail/CVE-2020-25649 2020-12-03 2023-02-02 2020-12-03 not_affected code_not_reachable com.fasterxml.jackson.core:jackson-databind is a library which contains the general-purpose data-binding functionality and tree-model for Jackson Data Processor. Affected versions of this package are vulnerable to XML External Entity (XXE) Injection. A flaw was found in FasterXML Jackson Databind, where it does not have entity expansion secured properly in the DOMDeserializer class. The highest threat from this vulnerability is data integrity. +```json +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "version": 1, + "metadata": { + "timestamp": "2023-10-12T19:07:00Z", + "properties": [ + ... + ] + } +} ``` -###### Example: Vulnerability list summary - -This example shows the default text output from using the `--summary` flag: +Apply the following IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-replace-version-timestamp.json](test/patch/cdx-patch-example-replace-version-timestamp.json): -```bash -./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json --quiet --summary +```json +[ + { "op": "replace", "path": "/version", "value": 2 }, + { "op": "replace", "path": "/metadata/timestamp", "value": "2024-01-24T22:50:18+00:00" } +] ``` +Invoke the patch command as follows: + ```bash -id cvss-severity source-name published description --- ------------- ----------- --------- ----------- -CVE-2023-42004 CVSSv31: 7.5 (high) NVD 2023-10-02 In FasterXML jackson-databind before 2.13.4, resource exhaustion can occur because of a lack of a check in BeanDeserializer._deserializeFromArray to prevent use of deeply nested arrays. An application is vulnerable only with certain customized choices for deserialization. -CVE-2023-42003 CVSSv31: 7.5 (high) NVD 2023-10-02 In FasterXML jackson-databind before 2.14.0-rc1, resource exhaustion can occur because of a lack of a check in primitive value deserializers to avoid deep wrapper array nesting, when the UNWRAP_SINGLE_VALUE_ARRAYS feature is enabled. Additional fix version in 2.13.4.1 and 2.12.17.1 -CVE-2020-25649 CVSSv31: 7.5 (high) NVD 2020-12-03 com.fasterxml.jackson.core:jackson-databind is a library which contains the general-purpose data-binding functionality and tree-model for Jackson Data Processor. Affected versions of this package are vulnerable to XML External Entity (XXE) Injection. A flaw was found in FasterXML Jackson Databind, where it does not have entity expansion secured properly in the DOMDeserializer class. The highest threat from this vulnerability is data integrity. +./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-replace-version-timestamp.json -q ``` -##### Example: Vulnerability list with `--where` filter with `description` key +The patched, output BOM has both an updated `version` and `timestamp`: -```bash -./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json --quiet --where description=XXE +```json +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "version": 2, + "metadata": { + "timestamp": "2024-01-24T22:50:18+00:00", + "properties": [ + ... + } +} ``` -```bash -id bom-ref cwe-ids cvss-severity source-name source-url published updated created rejected analysis-state analysis-justification description --- ------- ------- ------------- ----------- ---------- --------- ------- ------- -------- -------------- ---------------------- ----------- -CVE-2020-25649 611 CVSSv31: 7.5 (high), CVSSv31: 8.2 (high), CVSSv31: 0 (none) NVD https://nvd.nist.gov/vuln/detail/CVE-2020-25649 2020-12-03 2023-02-02 2020-12-03 not_affected code_not_reachable com.fasterxml.jackson.core:jackson-databind is a library which contains the general-purpose data-binding functionality and tree-model for Jackson Data Processor. Affected versions of this package are vulnerable to XML External Entity (XXE) Injection. A flaw was found in FasterXML Jackson Databind, where it does not have entity expansion secured properly in the DOMDeserializer class. The highest threat from this vulnerability is data integrity. -``` +##### Patch example 6: "remove" `property` from the `metadata.properties` array -##### Example: Vulnerability list with `--where` filter with `analysis-state` key +This example shows how the patch's "remove" operation can be used to remove a `property` object from the `metadata.properties` array using an index. -```bash -./sbom-utility vulnerability list -i test/vex/cdx-1-3-example1-bom-vex.json --quiet --where analysis-state=not_affected -``` +Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json): -```bash -id bom-ref cwe-ids cvss-severity source-name source-url published updated created rejected analysis-state analysis-justification description --- ------- ------- ------------- ----------- ---------- --------- ------- ------- -------- -------------- ---------------------- ----------- -CVE-2020-25649 611 CVSSv31: 7.5 (high), CVSSv31: 8.2 (high), CVSSv31: 0 (none) NVD https://nvd.nist.gov/vuln/detail/CVE-2020-25649 2020-12-03 2023-02-02 2020-12-03 not_affected code_not_reachable com.fasterxml.jackson.core:jackson-databind is a library which contains the general-purpose data-binding functionality and tree-model for Jackson Data Processor. Affected versions of this package are vulnerable to XML External Entity (XXE) Injection. A flaw was found in FasterXML Jackson Databind, where it does not have entity expansion secured properly in the DOMDeserializer class. The highest threat from this vulnerability is data integrity. +```json +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "version": 1, + "metadata": { + "timestamp": "2023-10-12T19:07:00Z", + "properties": [ + { + "name": "Property 1", + "value": "Value 1" + }, + { + "name": "Property 2", + "value": "Value 2" + } + ] + } +} ``` ---- - -### Diff - -This *experimental* command will compare two *similar* BOMs and return the delta (or "diff") in JSON (diff-patch format) or text. This functionality is based upon code ancestral to that used to report file diffs between `git commit`s. +Apply the following IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-remove-metadata-property.json](test/patch/cdx-patch-example-remove-metadata-property.json): -##### Notes +```json +[ + { "op": "remove", "path": "/metadata/properties/1" } +] +``` -- This command is undergoing analysis and tests which are exposing some underlying issues around "moved" objects in dependent diff-patch packages that may not be fixable and have no alternatives. - - *Specifically, the means by which "moved" objects are assigned "similarity" scores appears flawed in the case of JSON.* - - *Additionally, some of the underlying code relies upon Go maps which do not preserve key ordering.* +Invoke the patch command as follows: -#### Diff supported output formats +```bash +./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-remove-metadata-property.json -q +``` -Use the `--format` flag on the to choose one of the supported output formats: +The `property` at index `1` of the `metadata.properties` array has been removed: -- txt (default), json +```json +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "version": 1, + "metadata": { + "timestamp": "2023-10-12T19:07:00Z", + "properties": [ + { + "name": "Property 1", + "value": "Value 1" + } + ] + } +} +``` -#### Diff Examples +##### Patch example 7: "test" `property` exists in the `metadata.properties` array -##### Example: Add, delete and modify +This example shows how the patch records's can "test" for values or objects in a BOM. The utility will confirm "success" (using an `[INFO]` log message); otherwise, the utility will exit and return an error and generate an `[ERROR]` log message. -```bash -./sbom-utility diff -i test/diff/json-array-order-change-with-add-and-delete-base.json -r test/diff/json-array-order-change-with-add-and-delete-delta.json --quiet --format txt --colorize=true -``` +Original CycloneDX JSON BOM file: [test/patch/cdx-1-5-simplest-base.json](test/patch/cdx-1-5-simplest-base.json): -```bash - { - "licenses": [ - 0: { - "license": { -- "id": "Apache-1.0" -+ "id": "GPL-2.0" - } - }, --+ 2=>1: { --+ "license": { --+ "id": "GPL-3.0-only" --+ } --+ }, - 2: { - "license": { - "id": "GPL-3.0-only" - } - }, - 3: { - "license": { - "id": "MIT" - } - } - ] - } +```json +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "version": 1, + "metadata": { + "timestamp": "2023-10-12T19:07:00Z", + "properties": [ + { + "name": "Property 1", + "value": "Value 1" + }, + { + "name": "Property 2", + "value": "Value 2" + } + ] + } +} ``` ---- - -#### Completion +Apply the following IETF RFC6902 JSON Patch file: [test/patch/cdx-patch-example-test-metadata-property.json](test/patch/cdx-patch-example-test-metadata-property.json): -This command will generate command-line completion scripts, for the this utility, customized for various supported shells. +```json +[ + { "op": "test", "path": "/metadata/properties/1", "value": + { + "name": "Property 2", + "value": "Value 2" + } + } +] +``` -The completion command can be invoked as follows: +Invoke the patch command as follows: ```bash -./sbom_utility completion [shell] +./sbom-utility patch --input-file test/patch/cdx-1-5-simplest-base.json --patch-file test/patch/cdx-patch-example-test-metadata-property.json -q ``` -where valid values for `shell` are: - -- bash -- fish -- powershell -- zsh - ---- - -### Help +An informational (i.e., `[INFO]`) message is logged with `success` since the property object was found in the input BOM: -The utility supports the `help` command for the root command as well as any supported commands +```json +[INFO] IETF RFC6902 test operation success. test record: { + "op": "test", + "path": "/metadata/properties/1", + "value": { + "name": "Property 2", + "value": "Value 2" + } +} +``` -For example, to list top-level (root command) help which lists the supported "Available Commands": +If instead, we [tested for a different property](test/patch/cdx-patch-example-test-metadata-property-err.json) object: -```bash -./sbom-utility help +```json +[ + { "op": "test", "path": "/metadata/properties/1", "value": + { + "name": "Property 3", + "value": "Value 3" + } + } +] ``` -A specific command-level help listing is also available. For example, you can access the help for the `validate` command: +an error (i.e., `[ERROR]`) would be returned from the utility: -```bash -./sbom-utility help validate +```json +[ERROR] IETF RFC6902 test operation error. test record: { + "op": "test", + "path": "/metadata/properties/1", + "value": { + "name": "Property 3", + "value": "Value 3" + } +} ``` --- diff --git a/cmd/patch_verify_test.go b/cmd/patch_verify_test.go index d7f06bc6..8fba35dc 100644 --- a/cmd/patch_verify_test.go +++ b/cmd/patch_verify_test.go @@ -227,24 +227,3 @@ func sliceContainsValue(slice []interface{}, value interface{}) (foundValue inte } return } - -// func sliceContainsValueAtIndex(slice []interface{}, value interface{}, index int) (contains bool, err error) { -// getLogger().Enter() -// defer getLogger().Exit() - -// lenSlice := len(slice) -// if index < 0 { -// err = fmt.Errorf("index out of range. index: %v, slice range: %v", index, lenSlice) -// return -// } - -// var foundIndex int -// _, foundIndex, contains, err = sliceContainsValue(slice, value) - -// if index == foundIndex { -// contains = true -// return -// } - -// return -// }