Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(vuln): enable --vex for all targets #5992

Merged
merged 4 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ trivy filesystem [flags] PATH
--token-header string specify a header name for token in client/server mode (default "Trivy-Token")
--trace enable more verbose trace output for custom queries
--username strings username. Comma-separated usernames allowed.
--vex string [EXPERIMENTAL] file path to VEX
--vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library])
```

Expand Down
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_image.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ trivy image [flags] IMAGE_NAME
--token-header string specify a header name for token in client/server mode (default "Trivy-Token")
--trace enable more verbose trace output for custom queries
--username strings username. Comma-separated usernames allowed.
--vex string [EXPERIMENTAL] file path to VEX
--vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library])
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ trivy kubernetes [flags] { cluster | all | specific resources like kubectl. eg:
--tolerations strings specify node-collector job tolerations (example: key1=value1:NoExecute,key2=value2:NoSchedule)
--trace enable more verbose trace output for custom queries
--username strings username. Comma-separated usernames allowed.
--vex string [EXPERIMENTAL] file path to VEX
--vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library])
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ trivy repository [flags] (REPO_PATH | REPO_URL)
--token-header string specify a header name for token in client/server mode (default "Trivy-Token")
--trace enable more verbose trace output for custom queries
--username strings username. Comma-separated usernames allowed.
--vex string [EXPERIMENTAL] file path to VEX
--vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library])
```

Expand Down
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_rootfs.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ trivy rootfs [flags] ROOTDIR
--token-header string specify a header name for token in client/server mode (default "Trivy-Token")
--trace enable more verbose trace output for custom queries
--username strings username. Comma-separated usernames allowed.
--vex string [EXPERIMENTAL] file path to VEX
--vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library])
```

Expand Down
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_vm.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ trivy vm [flags] VM_IMAGE
--tf-exclude-downloaded-modules exclude misconfigurations for downloaded terraform modules
--token string for authentication in client/server mode
--token-header string specify a header name for token in client/server mode (default "Trivy-Token")
--vex string [EXPERIMENTAL] file path to VEX
--vuln-type strings comma-separated list of vulnerability types (os,library) (default [os,library])
```

Expand Down
119 changes: 88 additions & 31 deletions docs/docs/supply-chain/vex.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
This feature might change without preserving backwards compatibility.

Trivy supports filtering detected vulnerabilities using [the Vulnerability Exploitability Exchange (VEX)](https://www.ntia.gov/files/ntia/publications/vex_one-page_summary.pdf), a standardized format for sharing and exchanging information about vulnerabilities.
By providing VEX alongside the Software Bill of Materials (SBOM) during scanning, it is possible to filter vulnerabilities based on their status.
By providing VEX during scanning, it is possible to filter vulnerabilities based on their status.
Currently, Trivy supports the following three formats:

- [CycloneDX](https://cyclonedx.org/capabilities/vex/)
Expand All @@ -14,6 +14,15 @@ Currently, Trivy supports the following three formats:
This is still an experimental implementation, with only minimal functionality added.

## CycloneDX
| Target | Supported |
|:---------------:|:---------:|
| Container Image | |
| Filesystem | |
| Code Repository | |
| VM Image | |
| Kubernetes | |
| SBOM | ✅ |

There are [two VEX formats](https://cyclonedx.org/capabilities/vex/) for CycloneDX:

- Independent BOM and VEX BOM
Expand All @@ -28,7 +37,7 @@ The following steps are required:
2. Create a VEX based on the SBOM generated in step 1
3. Provide the VEX when scanning the CycloneDX SBOM

### Generating the SBOM
### Generate the SBOM
You can generate a CycloneDX SBOM with Trivy as follows:

```shell
Expand Down Expand Up @@ -117,23 +126,24 @@ Total: 1 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
CVE-2020-8911 is no longer shown as it is filtered out according to the given CycloneDX VEX document.

## OpenVEX
| Target | Supported |
|:---------------:|:---------:|
| Container Image | ✅ |
| Filesystem | ✅ |
| Code Repository | ✅ |
| VM Image | ✅ |
| Kubernetes | ✅ |
| SBOM | ✅ |

Trivy also supports [OpenVEX][openvex] that is designed to be minimal, compliant, interoperable, and embeddable.
Since OpenVEX aims to be SBOM format agnostic, both CycloneDX and SPDX formats are available for use as input SBOMs in Trivy.
OpenVEX can be used in all Trivy targets, unlike CycloneDX VEX.

The following steps are required:

1. Generate a SBOM (CycloneDX or SPDX)
2. Create a VEX based on the SBOM generated in step 1
3. Provide the VEX when scanning the SBOM
1. Create a VEX document
2. Provide the VEX when scanning your target

### Generating the SBOM
You can generate a CycloneDX or SPDX SBOM with Trivy as follows:

```shell
$ trivy image --format spdx-json --output debian11.spdx.json debian:11
```

### Create the VEX
### Create the VEX document
Please see also [the example](https://github.com/openvex/examples).
In Trivy, [the Package URL (PURL)][purl] is used as the product identifier.

Expand Down Expand Up @@ -167,11 +177,11 @@ In the above example, PURLs, located in `packages.externalRefs.referenceLocator`
`pkg:deb/debian/curl@7.50.3-1` in OpenVEX matches `pkg:deb/debian/curl@7.50.3-1?arch=i386`,
while `pkg:deb/debian/curl@7.50.3-1?arch=amd64` does not match `pkg:deb/debian/curl@7.50.3-1?arch=i386`.

### Scan SBOM with VEX
Provide the VEX when scanning the SBOM.
### Scan with VEX
Provide the VEX when scanning your target.

```
$ trivy sbom debian11.spdx.json --vex debian11.openvex
$ trivy image debian:11 --vex debian11.openvex
...
2023-04-26T17:56:05.358+0300 INFO Filtered out the detected vulnerability {"VEX format": "OpenVEX", "vulnerability-id": "CVE-2019-8457", "status": "not_affected", "justification": "vulnerable_code_not_in_execute_path"}

Expand All @@ -182,25 +192,25 @@ Total: 80 (UNKNOWN: 0, LOW: 58, MEDIUM: 6, HIGH: 16, CRITICAL: 0)

CVE-2019-8457 is no longer shown as it is filtered out according to the given OpenVEX document.

[openvex]: https://github.com/openvex/spec
[purl]: https://github.com/package-url/purl-spec

## CSAF
| Target | Supported |
|:---------------:|:---------:|
| Container Image | ✅ |
| Filesystem | ✅ |
| Code Repository | ✅ |
| VM Image | ✅ |
| Kubernetes | ✅ |
| SBOM | ✅ |

Trivy also supports [CSAF][csaf] format for VEX.
Since CSAF aims to be SBOM format agnostic, both CycloneDX and SPDX formats are available for use as input SBOMs in Trivy.

The following steps are required:

1. Generate a SBOM (CycloneDX or SPDX)
2. Create a CSAF document based on the SBOM generated in step 1
3. Provide the CSAF document when scanning the SBOM

### Generating the SBOM
You can generate a CycloneDX or SPDX SBOM with Trivy as follows:
1. Create a CSAF document
2. Provide the CSAF when scanning your target

```shell
$ trivy image --format spdx-json --output debian11.spdx.json debian:11
```

### Create the CSAF document
Create a CSAF document in JSON format as follows:
Expand Down Expand Up @@ -303,11 +313,11 @@ $ cat <<EOF > debian11.vex.csaf
EOF
```

### Scan SBOM with CSAF document
Provide the CSAF document when scanning the SBOM.
### Scan with CSAF VEX
Provide the CSAF document when scanning your target.

```console
$ trivy sbom debian11.spdx.json --vex debian11.vex.csaf
$ trivy image debian:11 --vex debian11.vex.csaf
...
2024-01-02T10:28:26.704+0100 INFO Filtered out the detected vulnerability {"VEX format": "CSAF", "vulnerability-id": "CVE-2019-8457", "status": "not_affected"}

Expand All @@ -318,4 +328,51 @@ Total: 80 (UNKNOWN: 0, LOW: 58, MEDIUM: 6, HIGH: 16, CRITICAL: 0)

CVE-2019-8457 is no longer shown as it is filtered out according to the given CSAF document.

## Appendix
### PURL matching
In the context of VEX, Package URLs (PURLs) are utilized to identify specific software packages and their versions.
The PURL matching specification outlines how PURLs are interpreted for vulnerability exception processing, ensuring precise identification and broad coverage of software packages.

!!! note
The following PURL matching rules are not formally defined within the current official PURL specification.
Instead, they represent [a community consensus][purl-matching] on how to interpret PURLs.

Below are the key aspects of the PURL matching rules:

#### Matching Without Version
A PURL without a specified version (e.g., `pkg:maven/com.google.guava/guava`) matches all versions of that package.
This rule simplifies the application of vulnerability exceptions to all versions of a package.

**Example**: `pkg:maven/com.google.guava/guava` matches:

- All versions of `guava`, such as `com.google.guava:guava:24.1.1`, `com.google.guava:guava:30.0`.

#### Matching Without Qualifiers
A PURL without any qualifiers (e.g., `pkg:maven/com.google.guava/guava@24.1.1`) matches any variation of that package, irrespective of qualifiers.
This approach ensures broad matching capabilities, covering all architectural or platform-specific variations of a package version.

**Example**: `pkg:maven/com.google.guava/guava@24.1.1` matches:

- `pkg:maven/com.google.guava/guava@24.1.1?classifier=x86`
- `pkg:maven/com.google.guava/guava@24.1.1?type=pom`

#### Matching With Specific Qualifiers
A PURL that includes specific qualifiers (e.g., `pkg:maven/com.google.guava/guava@24.1.1?classifier=x86`) matches only those package versions that include the same qualifiers.

**Example**: `pkg:maven/com.google.guava/guava@24.1.1?classifier=x86` matches:

- `pkg:maven/com.google.guava/guava@24.1.1?classifier=x86&type=dll`
- Extra qualifiers (e.g., `type=dll`) are ignored.

does not match:

- `pkg:maven/com.google.guava/guava@24.1.1`
- `classifier=x86` is missing.
- `pkg:maven/com.google.guava/guava@24.1.1?classifier=sources`
- `classifier` must have the same value.


[csaf]: https://oasis-open.github.io/csaf-documentation/specification.html
[openvex]: https://github.com/openvex/spec
[purl]: https://github.com/package-url/purl-spec
[purl-matching]: https://github.com/openvex/spec/issues/27
14 changes: 1 addition & 13 deletions pkg/flag/sbom_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,20 @@ var (
Usage: "deprecated",
Deprecated: true,
}
VEXFlag = Flag{
Name: "vex",
ConfigName: "sbom.vex",
Default: "",
Usage: "[EXPERIMENTAL] file path to VEX",
}
)

type SBOMFlagGroup struct {
ArtifactType *Flag // deprecated
SBOMFormat *Flag // deprecated
VEXPath *Flag
}

type SBOMOptions struct {
VEXPath string
}

func NewSBOMFlagGroup() *SBOMFlagGroup {
return &SBOMFlagGroup{
ArtifactType: &ArtifactTypeFlag,
SBOMFormat: &SBOMFormatFlag,
VEXPath: &VEXFlag,
}
}

Expand All @@ -55,7 +46,6 @@ func (f *SBOMFlagGroup) Flags() []*Flag {
return []*Flag{
f.ArtifactType,
f.SBOMFormat,
f.VEXPath,
}
}

Expand All @@ -69,7 +59,5 @@ func (f *SBOMFlagGroup) ToOptions() (SBOMOptions, error) {
return SBOMOptions{}, xerrors.New("'--artifact-type' and '--sbom-format' are no longer available")
}

return SBOMOptions{
VEXPath: getString(f.VEXPath),
}, nil
return SBOMOptions{}, nil
}
11 changes: 11 additions & 0 deletions pkg/flag/vulnerability_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,33 @@ var (
Values: dbTypes.Statuses,
Usage: "comma-separated list of vulnerability status to ignore",
}
VEXFlag = Flag{
Name: "vex",
ConfigName: "vulnerability.vex",
Default: "",
Usage: "[EXPERIMENTAL] file path to VEX",
}
)

type VulnerabilityFlagGroup struct {
VulnType *Flag
IgnoreUnfixed *Flag
IgnoreStatus *Flag
VEXPath *Flag
}

type VulnerabilityOptions struct {
VulnType []string
IgnoreStatuses []dbTypes.Status
VEXPath string
}

func NewVulnerabilityFlagGroup() *VulnerabilityFlagGroup {
return &VulnerabilityFlagGroup{
VulnType: &VulnTypeFlag,
IgnoreUnfixed: &IgnoreUnfixedFlag,
IgnoreStatus: &IgnoreStatusFlag,
VEXPath: &VEXFlag,
}
}

Expand All @@ -65,6 +74,7 @@ func (f *VulnerabilityFlagGroup) Flags() []*Flag {
f.VulnType,
f.IgnoreUnfixed,
f.IgnoreStatus,
f.VEXPath,
}
}

Expand Down Expand Up @@ -95,5 +105,6 @@ func (f *VulnerabilityFlagGroup) ToOptions() VulnerabilityOptions {
return VulnerabilityOptions{
VulnType: getStringSlice(f.VulnType),
IgnoreStatuses: ignoreStatuses,
VEXPath: getString(f.VEXPath),
}
}
Loading