diff --git a/content/scout/explore/exceptions.md b/content/scout/explore/exceptions.md index 2493460165..adbb2a3711 100644 --- a/content/scout/explore/exceptions.md +++ b/content/scout/explore/exceptions.md @@ -9,9 +9,8 @@ keywords: scout, cves, suppress, vex, exceptions Vulnerabilities found in container images sometimes need additional context. Just because an image contains a vulnerable package, it doesn't mean that the -vulnerability is exploitable. **Exceptions** in Docker Scout lets you address -false positives in image analysis using Vulnerability Exploitability -eXchange (VEX) documents. +vulnerability is exploitable. **Exceptions** in Docker Scout lets you +acknowledge accepted risks or address false positives in image analysis. By negating non-applicable vulnerabilities, you can make it easier for yourself and downstream consumers of your images to understand the security implications @@ -21,296 +20,84 @@ In Docker Scout, exceptions are automatically factored into the results. If an image contains an exception that flags a CVE as non-applicable, then that CVE is excluded from analysis results. -## Create an exception +## Create exceptions -To add an exception to an image, you need a VEX document. VEX is a standard -format for documenting vulnerabilities in the context of a software package or -product. +To create an exception for an image, you can: -There are multiple implementations and formats of VEX. Docker Scout supports -the [OpenVex](https://github.com/openvex/spec) implementation. To create an -OpenVEX document, use the [`vexctl`](https://github.com/openvex/vexctl) command -line tool. +- Create an exception in the [GUI](/scout/how-tos/create-exceptions-gui.md) of + Docker Scout Dashboard. -The following example command creates a VEX document stating that: +- Create a [VEX](/scout/how-tos/create-exceptions-vex.md) document and attach + it to the image. -- The software product described by this VEX document is the Docker image - `example/app:v1` -- The image contains the npm package `express@4.17.1` -- The npm package is affected by a known vulnerability: `CVE-2022-24999` -- The image is unaffected by the CVE, because the vulnerable code is never - executed in containers that run this image - -```console -$ vexctl create \ - --author="author@example.com" \ - --product="pkg:docker/example/app@v1" \ - --subcomponents="pkg:npm/express@4.17.1" \ - --vuln="CVE-2022-24999" \ - --status="not_affected" \ - --justification="vulnerable_code_not_in_execute_path" \ - --file="CVE-2022-24999.vex.json" -``` - -Here's a description of the options in this example: - -`--author` -: The email of the author of the VEX document. - -`--product` -: Package URL (PURL) of the Docker image. A PURL is an identifier - for the image in a standardized format, defined in the PURL - [specification](https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#docker). - - Docker image PURL strings begin with a `pkg:docker` type prefix, followed by - the image repository and version (the image tag or SHA256 digest). Unlike - image tags, where the version is specified like `example/app:v1`, in PURL the - image repository and version are separated by an `@`. - -`--subcomponents` -: PURL of the vulnerable package in the image. In this example, the - vulnerability exists in an npm package, so the `--subcomponents` PURL is the - identifier for the npm package name and version (`pkg:npm/express@4.17.1`). - - If the same vulnerability exists in multiple packages, `vexctl` lets you - specify the `--subcomponents` flag multiple times for a single `create` - command. - - You can also omit `--subcomponents`, in which case the VEX statement applies - to the entire image. - -`--vuln` -: ID of the CVE that the VEX statement addresses. - -`--status` -: This is the status label of the vulnerability. This describes the - relationship between the software (`--product`) and the CVE (`--vuln`). - The possible values for the status label in OpenVEX are: - - - `not_affected` - - `affected` - - `fixed` - - `under_investigation` - - In this example, the VEX statement asserts that the Docker image is - `not_affected` by the vulnerability. The `not_affected` status is the only - status that results in CVE suppression, where the CVE is filtered out of the - analysis results. The other statuses are useful for documentation purposes, - but they do not work for creating exceptions. For more information about all - the possible status labels, see [Status Labels](https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md#status-labels) - in the OpenVEX specification. - -`--justification` -: Justifies the `not_affected` status label, informing why the product is not - affected by the vulnerability. In this case, the justification given is - `vulnerable_code_not_in_execute_path`, signalling that the vulnerability - can't be executed as used by the product. - - In OpenVEX, status justifications can have one of the five possible values: - - - `component_not_present` - - `vulnerable_code_not_present` - - `vulnerable_code_not_in_execute_path` - - `vulnerable_code_cannot_be_controlled_by_adversary` - - `inline_mitigations_already_exist` - - For more information about these values and their definitions, see - [Status Justifications](https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md#status-justifications) - in the OpenVEX specification. - -`--file` -: Filename of the VEX document output - -Here's the OpenVEX JSON generated by this command: - -```json -{ - "@context": "https://openvex.dev/ns/v0.2.0", - "@id": "https://openvex.dev/docs/public/vex-749f79b50f5f2f0f07747c2de9f1239b37c2bda663579f87a35e5f0fdfc13de5", - "author": "author@example.com", - "timestamp": "2024-05-27T13:20:22.395824+02:00", - "version": 1, - "statements": [ - { - "vulnerability": { - "name": "CVE-2022-24999" - }, - "timestamp": "2024-05-27T13:20:22.395829+02:00", - "products": [ - { - "@id": "pkg:docker/example/app@v1", - "subcomponents": [ - { - "@id": "pkg:npm/express@4.17.1" - } - ] - } - ], - "status": "not_affected", - "justification": "vulnerable_code_not_in_execute_path" - } - ] -} -``` - -Understanding how VEX documents are supposed to be structured can be a bit of a -mouthful. The [OpenVEX specification](https://github.com/openvex/spec) -describes the format and all the possible properties of documents and -statements. For the full details, refer to the specification to learn more -about the available fields and how to create a well-formed OpenVEX document. - -To learn more about the available flags and syntax of the `vexctl` CLI tool and -how to install it, refer to the [`vexctl` GitHub repository](https://github.com/openvex/vexctl). - -For an introduction to VEX, you may also want to check out this use-case guide: -[Suppress image vulnerabilities with VEX](/scout/guides/vex.md). - -## Verifying VEX documents - -To test whether the VEX documents you create are well-formed and produce the -expected results, use the `docker scout cves` command with the `--vex-location` -flag to apply a VEX document to a local image analysis using the CLI. - -The following command invokes a local image analysis that incorporates all VEX -documents in the specified location, using the `--vex-location` flag. In this -example, the CLI is instructed to look for VEX documents in the current working -directory. - -```console -$ docker scout cves --vex-location . -``` - -The output of the `docker scout cves` command displays the results with any VEX -statements found in under the `--vex-location` location factored into the -results. For example, CVEs assigned a status of `not_affected` are filtered out -from the results. If the output doesn't seem to take the VEX statements into -account, that's an indication that the VEX documents might be invalid in some -way. - -Things to look out for include: - -- The PURL of a Docker image must begin with `pkg:docker/` followed by the image name. -- In a Docker image PURL, the image name and version is separated by `@`. - An image named `example/myapp:1.0` has the following PURL: `pkg:docker/example/myapp@1.0`. -- Remember to specify an `author` (it's a mandatory field in OpenVEX) -- The [OpenVEX specification](https://github.com/openvex/spec) describes how - and when to use `justification`, `impact_statement`, and other fields in the - VEX documents. Specifying these in an incorrect way results in an invalid - document. Make sure your VEX documents comply with the OpenVEX specification. - -## Attach exceptions to images - -When you've created an exception, -you can attach it to your image in the following ways: - -- Attach the document as an [attestation](#attestation) -- Embed the document in the [image filesystem](#image-filesystem) - -You can't remove a VEX document from an image once it's been added. For -documents attached as attestations, you can create a new VEX document and -attach it to the image again. Doing so will overwrite the previous VEX document -(but it won't remove the attestation). For images where the VEX document has -been embedded in the image's filesystem, you need to rebuild the image to -change the VEX document. - -### Attestation - -To attach exceptions as an attestation, you can use the `docker scout -attestation add` CLI command. Using attestations is the recommended option for attaching exceptions to -images. - -You can attach attestations to images that have already been pushed to a -registry. You don't need to build or push the image again. Additionally, having -the exceptions attached to the image as attestations means consumers can -inspect the exceptions for an image, directly from the registry. - -To attach an attestation to an image: - -1. Build the image and push it to a registry. - - ```console - $ docker build --provenance=true --sbom=true --tag --push . - ``` - -2. Attach the exception to the image as an attestation. - - ```console - $ docker scout attestation add \ - --file .vex.json \ - --predicate-type https://openvex.dev/ns/v0.2.0 \ - - ``` - - The options for this command are: - - - `--file`: the location and filename of the VEX document - - `--predicate-type`: the in-toto `predicateType` for OpenVEX - -### Image filesystem - -Embedding exceptions directly on the image filesystem is a good option if you -know the exceptions ahead of time, before you build the image. And it's easy; -just `COPY` the VEX document to the image in your Dockerfile. - -The downside with this approach is that you can't change or update the -exception later. Image layers are immutable, so anything you put in the image's -filesystem is there forever. Attaching the document as an -[attestation](#attestation) provides better flexibility. - -> [!NOTE] -> -> VEX documents embedded in the image filesystem are not considered for images -> that have attestations. If your image has **any** attestations, Docker Scout -> will only look for exceptions in the attestations, and not in the image -> filesystem. -> -> If you want to use the VEX document embedded in the image filesystem, you -> must remove the attestation from the image. Note that provenance attestations -> may be added automatically for images. To ensure that no attestations are -> added to the image, you can explicitly disable both SBOM and provenance -> attestations using the `--provenance=false` and `--sbom=false` flags when -> building the image. - -To embed a VEX document on the image filesystem, `COPY` the file into the image -as part of the image build. The following example shows how to copy all VEX -documents under `.vex/` in the build context, to `/var/lib/db` in the image. - -```dockerfile -# syntax=docker/dockerfile:1 - -FROM alpine -COPY .vex/* /var/lib/db/ -``` - -The filename of the VEX document must match the `*.vex.json` glob pattern. -It doesn't matter where on the image's filesystem you store the file. - -Note that the copied files must be part of the filesystem of the final image, -For multi-stage builds, the documents must persist in the final stage. +The recommended way to create exceptions is to use Docker Scout Dashboard. The +GUI provides a user-friendly interface for creating exceptions. It also lets +you create exceptions for multiple images, or your entire organization, all at +once. ## View exceptions -The **Exceptions** page on the [Docker Scout Dashboard](https://scout.docker.com/) -lists the exceptions for all images in your organization. Selecting a row in -the list opens the exception side panel, which displays more information about -the exception and where it comes from. +To view exceptions for images, you need to have the appropriate permissions. + +- Exceptions created [using the GUI](/scout/how-tos/create-exceptions-gui.md) + are visible to members of your Docker organization. Unauthenticated users or + users who aren't members of your organization cannot see these exceptions. +- Exceptions created [using VEX documents](/scout/how-tos/create-exceptions-vex.md) + are visible to anyone who can pull the image, since the VEX document is + stored in the image manifest or on filesystem of the image. + +### View exceptions in Docker Scout Dashboard + +The [**Exceptions** tab](https://scout.docker.com/reports/vulnerabilities/exceptions) +of the Vulnerabilities page in Docker Scout Dashboard lists all exceptions for +for all images in your organization. From here, you can see more details about +each exception, the CVEs being suppressed, the images that exceptions apply to, +the type of exception and how it was created, and more. + +For exceptions created using the [GUI](/scout/how-tos/create-exceptions-gui.md), +selecting the action menu lets you edit or remove the exception. To view all exceptions for a specific image tag: -{{< tabs >}} -{{< tab name="Docker Scout Dashboard" >}} - 1. Go to the [Images page](https://scout.docker.com/reports/images). 2. Select the tag that you want to inspect. -3. Open the **Image attestations** tab. +3. Open the **Exceptions** tab. -{{< /tab >}} -{{< tab name="Docker Desktop" >}} +### View exceptions in the CLI -1. Open the **Images** view in Docker Desktop. -2. Open the **Hub** tab. -3. Select the tag you want to inspect. -4. Open the **Image attestations** tab. +{{% experimental %}} +Viewing exceptions in the CLI is an experimental feature. +It requires the latest version of the Docker Scout CLI plugin. +Some exceptions may not appear correctly in the CLI. +{{% /experimental %}} -{{< /tab >}} -{{< /tabs >}} +Vulnerability exceptions are highlighted in the CLI when you run `docker scout +cves `. If a CVE is suppressed by an exception, a `SUPPRESSED` label +appears next to the CVE ID. Details about the exception are also displayed. + +![SUPPRESSED label in the CLI output](/scout/images/suppressed-cve-cli.png) + +> [!IMPORTANT] +> In order to view exceptions in the CLI, you must configure the CLI to use +> the same Docker organization that you used to create the exceptions. +> +> To configure an organization for the CLI, run: +> +> ```console +> $ docker scout configure organization +> ``` +> +> Replace `` with the name of your Docker organization. +> +> You can also set the organization on a per-command basis by using the +> `--org` flag: +> +> ```console +> $ docker scout cves --org +> ``` + +To exclude suppressed CVEs from the output, use the `--ignore-suppressed` flag: + +```console +$ docker scout cves --ignore-suppressed +``` diff --git a/content/scout/guides/vex.md b/content/scout/guides/vex.md deleted file mode 100644 index b72a29045b..0000000000 --- a/content/scout/guides/vex.md +++ /dev/null @@ -1,300 +0,0 @@ ---- -title: Suppress image vulnerabilities with VEX -description: An introduction to using VEX with Docker Scout -keywords: scout, vex, Vulnerability Exploitability eXchange, openvex, vulnerabilities, cves ---- - -Vulnerability Exploitability eXchange (VEX) is a way to add context -about how a software product is affected by a vulnerable component. -In this guide, you will learn about: - -- How VEX can help you suppress non-applicable or fixed vulnerabilities found in your images -- How to create VEX documents and statements -- How to apply and consume VEX data with Docker Scout - -> **Experimental** -> -> Support for VEX is an experimental feature in Docker Scout. -> We recommend that you do not use this feature in production environments -> as this feature may change or be removed from future releases. -{ .experimental } - -## Prerequisites - -If you want to follow along the steps of this guide, you'll need the following: - -- The latest version of Docker Desktop -- The [containerd image store](../../desktop/containerd.md) must be enabled -- Git -- A [Docker account](/accounts/create-account/) -- A GitHub account - -## Introduction to VEX - -Just because a software product contains a vulnerable component, -it doesn't mean that the vulnerability is exploitable. -For example, the vulnerable component might never be -loaded into memory when the application runs. -Or the vulnerability might have been fixed, -but the system that detects the vulnerability is unaware. - -The concept of VEX is defined by a working group by -the United States Cybersecurity and Infrastructure Security Agency (CISA). -At the core of VEX are exploitability assessments. -These assessments describe the status of a given CVE for a product. -The possible vulnerability statuses in VEX are: - -- Not affected: No remediation is required regarding this vulnerability. -- Affected: Actions are recommended to remediate or address this vulnerability. -- Fixed: These product versions contain a fix for the vulnerability. -- Under investigation: It is not yet known whether these product versions are affected by the vulnerability. An update will be provided in a later release. - -There are multiple implementations of VEX, -and the exact format and properties of a VEX document differ -depending on the implementation of VEX that you use. -Examples of VEX implementations include: - -- OpenVEX -- Open Security Advisory Framework (OSAF) -- CycloneDX -- SPDX - -This guide uses the OpenVEX implementation in its examples. -For more information about OpenVEX, -refer to the [specification](https://github.com/openvex/spec). - -In all implementations, the core idea is the same: -to provide a framework for describing the impact of vulnerabilities. -Key components of VEX regardless of implementation includes: - -VEX document -: A type of security advisory for storing VEX statements. - The format of the document depends on the specific implementation. - -VEX statement -: Describes the status of a vulnerability in a product, - whether it's exploitable, and whether there are ways to remediate the issue. - -Justification and impact -: Depending on the vulnerability status, statements include a justification - or impact statement describing why a product is or isn't affected. - -Action statements -: Describe how to remediate or mitigate the vulnerability. - -This added context that VEX provides around vulnerabilities -helps organizations perform risk assessment of software products. - -## Create and enable a repository - -To get started, create a sample project to work with. -Use the [Docker Scout demo service](https://github.com/docker/scout-demo-service) -template repository to bootstrap a new repository in your own GitHub organization. - -1. Create the repository from the template. -2. Clone the Git repository to your machine. -3. Build an image from the repository and push it to a new Docker Hub repository. - - ```console - $ cd scout-demo-service - $ docker build --provenance=true --sbom=true --tag /scout-demo-service:v1 --push . - ``` - -4. Enable Docker Scout on the repository. - - ```console - $ docker scout repo enable /scout-demo-service - ``` - -## Inspect vulnerability - -Use the `docker scout cves` command to view the vulnerabilities for the image. -For the purpose of this guide, we'll concentrate on a particular CVE: CVE-2022-24999. - -```console -$ docker scout cves --only-cve-id CVE-2022-24999 -``` - -The output from this command shows that this CVE affects two JavaScript packages -in the image: `express@4.17.1` and `qs@6.7.0`. - -Now, let's imagine that you've reviewed this vulnerability -and determined that the exploit doesn't affect your application -because the vulnerable code is never executed. -Your image would still show as containing a `HIGH` severity vulnerability, -merely by having the component in the SBOM. - -This is a situation where VEX can help suppress the CVE for your product. - -## Create a VEX document - -OpenVEX, the implementation of VEX used in this guide, -provides a CLI tool for generating VEX documents called `vexctl`. -If you have Go installed on your system, -you can install `vexctl` using the `go install` command: - -```console -$ go install github.com/openvex/vexctl@latest -``` - -Otherwise, you can grab a prebuilt binary from the `vexctl` -[releases page](https://github.com/openvex/vexctl/releases) on GitHub. - -Use the `vexctl create` command to create an OpenVEX document. -The following command creates a VEX document `CVE-2022-24999.vex.json` -which states that the Docker image and its sub-components -are unaffected by the CVE because the vulnerable code is never executed. - -```console -$ vexctl create \ - --author="author@example.com" \ - --product="pkg:docker//scout-demo-service@v1" \ - --subcomponents="pkg:npm/express@4.17.1" \ - --subcomponents="pkg:npm/qs@6.7.0" \ - --vuln="CVE-2022-24999" \ - --status="not_affected" \ - --justification="vulnerable_code_not_in_execute_path" \ - --file="CVE-2022-24999.vex.json" -``` - -This creates a VEX document that looks like this: - -```json -{ - "@context": "https://openvex.dev/ns/v0.2.0", - "@id": "https://openvex.dev/docs/public/vex-a7e7c69be57bc49dec9cc2f3a3e3329b12674ca53b53a53ab42134dcc0510779", - "author": "author@example.com", - "timestamp": "2024-02-03T09:33:28.913572+01:00", - "version": 1, - "statements": [ - { - "vulnerability": { - "name": "CVE-2022-24999" - }, - "timestamp": "2024-02-03T09:33:28.913574+01:00", - "products": [ - { - "@id": "pkg:docker//scout-demo-service@v1", - "subcomponents": [ - { - "@id": "pkg:npm/express@4.17.1" - }, - { - "@id": "pkg:npm/qs@6.7.0" - } - ] - } - ], - "status": "not_affected", - "justification": "vulnerable_code_not_in_execute_path" - } - ] -} -``` - -## Verify CVE suppression - -To test whether the VEX statement provides the expected security advisory, -use the `docker scout cves` command to review the CVE status. -The `--vex-location` flag lets you specify a directory containing VEX documents. - -```console -$ docker scout cves --only-cve-id CVE-2022-24999 --vex-location . -``` - -You should now see `VEX` fields appear in the output of the command. - -```text {hl_lines=[7,8]} -✗ HIGH CVE-2022-24999 [OWASP Top Ten 2017 Category A9 - Using Components with Known Vulnerabilities] - https://scout.docker.com/v/CVE-2022-24999 - Affected range : <4.17.3 - Fixed version : 4.17.3 - CVSS Score : 7.5 - CVSS Vector : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - VEX : not affected [vulnerable code not in execute path] - : author@example.com -``` - -## Attach VEX documents to images - -To distribute VEX statements together with your images, -you can embed the VEX document in an in-toto attestation. -This is also how BuildKit attaches SBOM and provenance attestations to images. - -When you encapsulate a VEX document in an in-toto attestation, -the OpenVEX specification recommends a different format for the VEX document. -In-toto attestations already contain the image reference in the attestation predicate, -making the image reference in the `products` key of the VEX document redundant. -Instead, `products` should refer to the packages that contain the vulnerabilities -(`subcomponents` in the VEX document shown earlier). - -1. Create a new `in-toto.vex.json` document with the following contents: - - ```json - { - "@context": "https://openvex.dev/ns/v0.2.0", - "@id": "https://openvex.dev/docs/public/vex-a7e7c69be57bc49dec9cc2f3a3e3329b12674ca53b53a53ab42134dcc0510779", - "author": "author@example.com", - "timestamp": "2024-02-03T09:33:28.913572+01:00", - "version": 1, - "statements": [ - { - "vulnerability": { - "name": "CVE-2022-24999" - }, - "timestamp": "2024-02-03T09:33:28.913574+01:00", - "products": [ - { - "@id": "pkg:npm/express@4.17.1" - }, - { - "@id": "pkg:npm/qs@6.7.0" - } - ], - "status": "not_affected", - "justification": "vulnerable_code_not_in_execute_path" - } - ] - } - ``` - -2. Attach the `in-toto.vex.json` VEX document as an attestation: - - ```console - $ docker scout attestation add \ - --file in-toto.vex.json \ - --predicate-type https://openvex.dev/ns/v0.2.0 \ - /scout-demo-service:v1 - ``` - - This adds an in-toto attestation to the image, - with a predicate type of `https://openvex.dev/ns/v0.2.0`. - -3. Analyze the image with `docker scout cves`. - - > [!NOTE] - > - > This only works when analyzing remote images in a registry. - > To force Docker Scout to analyze a registry image instead of a local one, - > specify the image reference with a `registry://` prefix. - - ```console - $ docker scout cves \ - --only-cve-id CVE-2022-24999 \ - registry:///scout-demo-service:v1 - ``` - -## Summary - -In this guide, you've learned about: - -- How VEX is a concept that can help you optimize vulnerability triaging -- How to create VEX documents and use them in image analysis -- How you can distribute VEX with your images as in-toto attestations - -For more information about VEX: - -- [VEX Status Justifications (CISA)](https://www.cisa.gov/sites/default/files/publications/VEX_Status_Justification_Jun22.pdf) -- [VEX Use Cases (CISA)](https://www.cisa.gov/sites/default/files/publications/VEX_Use_Cases_Document_508c.pdf) -- [OpenVEX specification](https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md) -- [Manage vulnerability exceptions](/scout/explore/exceptions.md) diff --git a/content/scout/how-tos/create-exceptions-gui.md b/content/scout/how-tos/create-exceptions-gui.md new file mode 100644 index 0000000000..fae5197b42 --- /dev/null +++ b/content/scout/how-tos/create-exceptions-gui.md @@ -0,0 +1,78 @@ +--- +title: Create an exception using the GUI +description: Create an exception for a vulnerability in an image using the Docker Scout Dashboard. +keywords: Docker, Docker Scout, vulnerability, exception, create, GUI +--- + +The Docker Scout Dashboard provides a user-friendly interface for creating +[exceptions](/scout/explore/exceptions.md) for vulnerabilities found in +container images. Exceptions let you acknowledge accepted risks or address +false positives in image analysis. + +## Prerequisites + +To create an in the Docker Scout Dashboard, you need a Docker account with +**Editor** or **Owner** permissions for the Docker organization that owns the +image. + +## Steps + +To create an exception for a vulnerability in an image using the Docker Scout +Dashboard: + +1. Go to the [Images page](https://scout.docker.com/reports/images). +2. Select the image tag that contains the vulnerability you want to create an + exception for. +3. Open the **Image layers** tab. +4. Select the layer that contains the vulnerability you want to create an + exception for. +5. In the **Vulnerabilities** tab, find the vulnerability you want to create an + exception for. Vulnerabilities are grouped by package. Find the package that + contains the vulnerability you want to create an exception for, and then + expand the package. +6. Select the **Create exception** button next to the vulnerability. + +{{% create_panel.inline %}} +Selecting the **Create exception** button opens the **Create exception** side panel. +In this panel, you can provide the details of the exception: + +- **Exception type**: The type of exception. The only supported types are: + + - **Accepted risk**: The vulnerability is not addressed due to its minimal + security risk, high remediation costs, dependence on an upstream fix, or + similar. + - **False positive**: The vulnerability presents no security risk in your + specific use case, configuration, or because of measures in place that + block exploitation + + If you select **False positive**, you must provide a justification for why + the vulnerability is a false positive: + +- **Additional details**: Any additional information that you want to + provide about the exception. + +- **Scope**: The scope of the exception. The scope can be: + + - **Image**: The exception applies to the selected image. + - **All images in repository**: The exception applies to all images in the + repository. + - **Specific repository**: The exception applies to all images in the + specified repositories. + - **All images in my organization**: The exception applies to all images in + your organization. + +- **Package scope**: The scope of the exception. The package scope can be: + + - **Selected package**: The exception applies to the selected package. + - **Any packages**: The exception applies to all packages vulnerable to this + CVE. + +When you've filled in the details, select the **Create** button to create the +exception. + +The exception is now created and factored into the analysis results for the +images that you selected. The exception is also listed on the **Exceptions** +tab of the [Vulnerabilities page](https://scout.docker.com/reports/vulnerabilities/exceptions) +in the Docker Scout Dashboard. + +{{% /create_panel.inline %}} diff --git a/content/scout/how-tos/create-exceptions-vex.md b/content/scout/how-tos/create-exceptions-vex.md new file mode 100644 index 0000000000..ca645aad82 --- /dev/null +++ b/content/scout/how-tos/create-exceptions-vex.md @@ -0,0 +1,318 @@ +--- +title: Create an exception using the VEX +description: Create an exception for a vulnerability in an image using VEX documents. +keywords: Docker, vulnerability, exception, create, VEX +aliases: + - /scout/guides/vex/ +--- + +Vulnerability Exploitability eXchange (VEX) is a standard format for +documenting vulnerabilities in the context of a software package or product. +Docker Scout supports VEX documents to create +[exceptions](/scout/explore/exceptions.md) for vulnerabilities in images. + +> [!NOTE] +> You can also create exceptions using the Docker Scout Dashboard or Docker +> Desktop. The GUI provides a user-friendly interface for creating exceptions, +> and it's easy to manage exceptions for multiple images. It also lets you +> create exceptions for multiple images, or your entire organization, all at +> once. For more information, see [Create an exception using the GUI](/scout/how-tos/create-exceptions-gui.md). + +## Prerequisites + +To create exceptions using OpenVEX documents, you need: + +- The latest version of Docker Desktop or the Docker Scout CLI plugin +- The [`vexctl`](https://github.com/openvex/vexctl) command line tool. +- The [containerd image store](../../desktop/containerd.md) must be enabled +- Write permissions to the registry repository where the image is stored + +## Introduction to VEX + +The VEX standard is defined by a working group by the United States +Cybersecurity and Infrastructure Security Agency (CISA). At the core of VEX are +exploitability assessments. These assessments describe the status of a given +CVE for a product. The possible vulnerability statuses in VEX are: + +- Not affected: No remediation is required regarding this vulnerability. +- Affected: Actions are recommended to remediate or address this vulnerability. +- Fixed: These product versions contain a fix for the vulnerability. +- Under investigation: It is not yet known whether these product versions are affected by the vulnerability. An update will be provided in a later release. + +There are multiple implementations and formats of VEX. Docker Scout supports +the [OpenVex](https://github.com/openvex/spec) implementation. Regardless of +the specific implementation, the core idea is the same: to provide a framework +for describing the impact of vulnerabilities. Key components of VEX regardless +of implementation includes: + +VEX document +: A type of security advisory for storing VEX statements. + The format of the document depends on the specific implementation. + +VEX statement +: Describes the status of a vulnerability in a product, + whether it's exploitable, and whether there are ways to remediate the issue. + +Justification and impact +: Depending on the vulnerability status, statements include a justification + or impact statement describing why a product is or isn't affected. + +Action statements +: Describe how to remediate or mitigate the vulnerability. + +## `vexctl` example + +The following example command creates a VEX document stating that: + +- The software product described by this VEX document is the Docker image + `example/app:v1` +- The image contains the npm package `express@4.17.1` +- The npm package is affected by a known vulnerability: `CVE-2022-24999` +- The image is unaffected by the CVE, because the vulnerable code is never + executed in containers that run this image + +```console +$ vexctl create \ + --author="author@example.com" \ + --product="pkg:docker/example/app@v1" \ + --subcomponents="pkg:npm/express@4.17.1" \ + --vuln="CVE-2022-24999" \ + --status="not_affected" \ + --justification="vulnerable_code_not_in_execute_path" \ + --file="CVE-2022-24999.vex.json" +``` + +Here's a description of the options in this example: + +`--author` +: The email of the author of the VEX document. + +`--product` +: Package URL (PURL) of the Docker image. A PURL is an identifier + for the image in a standardized format, defined in the PURL + [specification](https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#docker). + + Docker image PURL strings begin with a `pkg:docker` type prefix, followed by + the image repository and version (the image tag or SHA256 digest). Unlike + image tags, where the version is specified like `example/app:v1`, in PURL the + image repository and version are separated by an `@`. + +`--subcomponents` +: PURL of the vulnerable package in the image. In this example, the + vulnerability exists in an npm package, so the `--subcomponents` PURL is the + identifier for the npm package name and version (`pkg:npm/express@4.17.1`). + + If the same vulnerability exists in multiple packages, `vexctl` lets you + specify the `--subcomponents` flag multiple times for a single `create` + command. + + You can also omit `--subcomponents`, in which case the VEX statement applies + to the entire image. + +`--vuln` +: ID of the CVE that the VEX statement addresses. + +`--status` +: This is the status label of the vulnerability. This describes the + relationship between the software (`--product`) and the CVE (`--vuln`). + The possible values for the status label in OpenVEX are: + + - `not_affected` + - `affected` + - `fixed` + - `under_investigation` + + In this example, the VEX statement asserts that the Docker image is + `not_affected` by the vulnerability. The `not_affected` status is the only + status that results in CVE suppression, where the CVE is filtered out of the + analysis results. The other statuses are useful for documentation purposes, + but they do not work for creating exceptions. For more information about all + the possible status labels, see [Status Labels](https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md#status-labels) + in the OpenVEX specification. + +`--justification` +: Justifies the `not_affected` status label, informing why the product is not + affected by the vulnerability. In this case, the justification given is + `vulnerable_code_not_in_execute_path`, signalling that the vulnerability + can't be executed as used by the product. + + In OpenVEX, status justifications can have one of the five possible values: + + - `component_not_present` + - `vulnerable_code_not_present` + - `vulnerable_code_not_in_execute_path` + - `vulnerable_code_cannot_be_controlled_by_adversary` + - `inline_mitigations_already_exist` + + For more information about these values and their definitions, see + [Status Justifications](https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md#status-justifications) + in the OpenVEX specification. + +`--file` +: Filename of the VEX document output + +## Example JSON document + +Here's the OpenVEX JSON generated by this command: + +```json +{ + "@context": "https://openvex.dev/ns/v0.2.0", + "@id": "https://openvex.dev/docs/public/vex-749f79b50f5f2f0f07747c2de9f1239b37c2bda663579f87a35e5f0fdfc13de5", + "author": "author@example.com", + "timestamp": "2024-05-27T13:20:22.395824+02:00", + "version": 1, + "statements": [ + { + "vulnerability": { + "name": "CVE-2022-24999" + }, + "timestamp": "2024-05-27T13:20:22.395829+02:00", + "products": [ + { + "@id": "pkg:docker/example/app@v1", + "subcomponents": [ + { + "@id": "pkg:npm/express@4.17.1" + } + ] + } + ], + "status": "not_affected", + "justification": "vulnerable_code_not_in_execute_path" + } + ] +} +``` + +Understanding how VEX documents are supposed to be structured can be a bit of a +mouthful. The [OpenVEX specification](https://github.com/openvex/spec) +describes the format and all the possible properties of documents and +statements. For the full details, refer to the specification to learn more +about the available fields and how to create a well-formed OpenVEX document. + +To learn more about the available flags and syntax of the `vexctl` CLI tool and +how to install it, refer to the [`vexctl` GitHub repository](https://github.com/openvex/vexctl). + +## Verifying VEX documents + +To test whether the VEX documents you create are well-formed and produce the +expected results, use the `docker scout cves` command with the `--vex-location` +flag to apply a VEX document to a local image analysis using the CLI. + +The following command invokes a local image analysis that incorporates all VEX +documents in the specified location, using the `--vex-location` flag. In this +example, the CLI is instructed to look for VEX documents in the current working +directory. + +```console +$ docker scout cves --vex-location . +``` + +The output of the `docker scout cves` command displays the results with any VEX +statements found in under the `--vex-location` location factored into the +results. For example, CVEs assigned a status of `not_affected` are filtered out +from the results. If the output doesn't seem to take the VEX statements into +account, that's an indication that the VEX documents might be invalid in some +way. + +Things to look out for include: + +- The PURL of a Docker image must begin with `pkg:docker/` followed by the image name. +- In a Docker image PURL, the image name and version is separated by `@`. + An image named `example/myapp:1.0` has the following PURL: `pkg:docker/example/myapp@1.0`. +- Remember to specify an `author` (it's a mandatory field in OpenVEX) +- The [OpenVEX specification](https://github.com/openvex/spec) describes how + and when to use `justification`, `impact_statement`, and other fields in the + VEX documents. Specifying these in an incorrect way results in an invalid + document. Make sure your VEX documents comply with the OpenVEX specification. + +## Attach VEX documents to images + +When you've created a VEX document, +you can attach it to your image in the following ways: + +- Attach the document as an [attestation](#attestation) +- Embed the document in the [image filesystem](#image-filesystem) + +You can't remove a VEX document from an image once it's been added. For +documents attached as attestations, you can create a new VEX document and +attach it to the image again. Doing so will overwrite the previous VEX document +(but it won't remove the attestation). For images where the VEX document has +been embedded in the image's filesystem, you need to rebuild the image to +change the VEX document. + +### Attestation + +To attach VEX documents as an attestation, you can use the `docker scout +attestation add` CLI command. Using attestations is the recommended option for +attaching exceptions to images when using VEX. + +You can attach attestations to images that have already been pushed to a +registry. You don't need to build or push the image again. Additionally, having +the exceptions attached to the image as attestations means consumers can +inspect the exceptions for an image, directly from the registry. + +To attach an attestation to an image: + +1. Build the image and push it to a registry. + + ```console + $ docker build --provenance=true --sbom=true --tag --push . + ``` + +2. Attach the exception to the image as an attestation. + + ```console + $ docker scout attestation add \ + --file .vex.json \ + --predicate-type https://openvex.dev/ns/v0.2.0 \ + + ``` + + The options for this command are: + + - `--file`: the location and filename of the VEX document + - `--predicate-type`: the in-toto `predicateType` for OpenVEX + +### Image filesystem + +Embedding VEX documents directly on the image filesystem is a good option if +you know the exceptions ahead of time, before you build the image. And it's +relatively easy; just `COPY` the VEX document to the image in your Dockerfile. + +The downside with this approach is that you can't change or update the +exception later. Image layers are immutable, so anything you put in the image's +filesystem is there forever. Attaching the document as an +[attestation](#attestation) provides better flexibility. + +> [!NOTE] +> VEX documents embedded in the image filesystem are not considered for images +> that have attestations. If your image has **any** attestations, Docker Scout +> will only look for exceptions in the attestations, and not in the image +> filesystem. +> +> If you want to use the VEX document embedded in the image filesystem, you +> must remove the attestation from the image. Note that provenance attestations +> may be added automatically for images. To ensure that no attestations are +> added to the image, you can explicitly disable both SBOM and provenance +> attestations using the `--provenance=false` and `--sbom=false` flags when +> building the image. + +To embed a VEX document on the image filesystem, `COPY` the file into the image +as part of the image build. The following example shows how to copy all VEX +documents under `.vex/` in the build context, to `/var/lib/db` in the image. + +```dockerfile +# syntax=docker/dockerfile:1 + +FROM alpine +COPY .vex/* /var/lib/db/ +``` + +The filename of the VEX document must match the `*.vex.json` glob pattern. +It doesn't matter where on the image's filesystem you store the file. + +Note that the copied files must be part of the filesystem of the final image, +For multi-stage builds, the documents must persist in the final stage. + diff --git a/content/scout/images/suppressed-cve-cli.png b/content/scout/images/suppressed-cve-cli.png new file mode 100644 index 0000000000..6384eb66a9 Binary files /dev/null and b/content/scout/images/suppressed-cve-cli.png differ diff --git a/content/scout/release-notes/platform.md b/content/scout/release-notes/platform.md index 54f4503a26..6d632133af 100644 --- a/content/scout/release-notes/platform.md +++ b/content/scout/release-notes/platform.md @@ -57,8 +57,6 @@ view in the Docker Scout Dashboard to see all exceptions that apply to a given image. For more information, see [Manage vulnerability exceptions](/scout/explore/exceptions.md). -If you're new to VEX, check out this use-case guide: -[Suppress image vulnerabilities with VEX](/scout/guides/vex.md). ### 2024-05-06 diff --git a/data/toc.yaml b/data/toc.yaml index 9a52c54382..8de7175e6a 100644 --- a/data/toc.yaml +++ b/data/toc.yaml @@ -253,8 +253,6 @@ Guides: title: Text summarization - path: /guides/use-case/jupyter/ title: Data science with JupyterLab - - path: /scout/guides/vex/ - title: Suppress CVEs with VEX - path: /guides/use-case/databases/ title: Use containerized databases @@ -1424,6 +1422,10 @@ Manuals: title: Metrics exporter - sectiontitle: How-tos section: + - path: /scout/how-tos/create-exceptions-gui/ + title: Create exceptions (GUI) + - path: /scout/how-tos/create-exceptions-vex/ + title: Create exceptions (VEX) - path: /scout/how-tos/artifact-types/ title: Specify artifact type or location - path: /scout/how-tos/view-create-sboms/