scout: create exceptions in dashboard

Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
This commit is contained in:
David Karlsson 2024-09-06 15:54:32 +02:00
parent b81f04a0c0
commit 2c891f052a
7 changed files with 468 additions and 585 deletions

View File

@ -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 <IMAGE> --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 <IMAGE> --push .
```
2. Attach the exception to the image as an attestation.
```console
$ docker scout attestation add \
--file <cve-id>.vex.json \
--predicate-type https://openvex.dev/ns/v0.2.0 \
<IMAGE>
```
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 <image>`. 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 <organization>
> ```
>
> Replace `<organization>` 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 <organization> <image>
> ```
To exclude suppressed CVEs from the output, use the `--ignore-suppressed` flag:
```console
$ docker scout cves --ignore-suppressed <image>
```

View File

@ -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 <ORG>/scout-demo-service:v1 --push .
```
4. Enable Docker Scout on the repository.
```console
$ docker scout repo enable <ORG>/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/<ORG>/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/<ORG>/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 \
<ORG>/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://<ORG>/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)

View File

@ -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 %}}

View File

@ -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 <IMAGE> --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 <IMAGE> --push .
```
2. Attach the exception to the image as an attestation.
```console
$ docker scout attestation add \
--file <cve-id>.vex.json \
--predicate-type https://openvex.dev/ns/v0.2.0 \
<IMAGE>
```
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.

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -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

View File

@ -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
@ -1447,6 +1445,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/