Skip to content

Commit

Permalink
feat(vuln): enable --vex for all targets (aquasecurity#5992)
Browse files Browse the repository at this point in the history
Signed-off-by: knqyf263 <knqyf263@gmail.com>
Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com>
  • Loading branch information
knqyf263 and DmitriyLewen authored Jan 25, 2024
1 parent f9da021 commit e2eb70e
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 44 deletions.
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_filesystem.md
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
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_kubernetes.md
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
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_repository.md
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),
}
}

0 comments on commit e2eb70e

Please sign in to comment.