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

docs: explain how VEX is applied #6864

Merged
merged 3 commits into from
Jun 6, 2024
Merged
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
101 changes: 101 additions & 0 deletions docs/docs/supply-chain/vex.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ $ trivy image ghcr.io/aquasecurity/trivy:0.50.0 --vex trivy.openvex.json
VEX documents can indeed be reused across different container images, eliminating the need to issue separate VEX documents for each image.
This is particularly useful when there is a common component or library that is used across multiple projects or container images.

You can see [the appendix](#applying-vex-to-dependency-trees) for more details on how VEX is applied in Trivy.

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

Expand Down Expand Up @@ -412,6 +414,8 @@ At present, the specified relationship category is not taken into account and al
- installed_on
- installed_with

You can see [the appendix](#applying-vex-to-dependency-trees) for more details on how VEX is applied in Trivy.

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

Expand Down Expand Up @@ -470,6 +474,103 @@ does not match:
- `pkg:maven/com.google.guava/[email protected]?classifier=sources`
- `classifier` must have the same value.

### Applying VEX to Dependency Trees

Trivy internally generates a dependency tree and applies VEX statements to this graph.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be confusing.
This logic is not related to the dependency tree display.

Let's consider a project with the following dependency tree, where `Module C v2.0.0` is assumed to have a vulnerability CVE-XXXX-YYYY:

```mermaid
graph TD;
modRootA(Module Root A v1.0.0)
modB(Module B v1.0.0)
modC(Module C v2.0.0)

modRootA-->modB
modB-->modC
```

Now, suppose a VEX statement is issued for `Module B` as follows:

```json
"statements": [
{
"vulnerability": {"name": "CVE-XXXX-YYYY"},
"products": [
{
"@id": "pkg:golang/[email protected]",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We check all parents of the dependency tree.
Can we add information that either parent can be used(parent of parent, etc.)?
I mean is that for this case we can choose module-b or module-a.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added 51e8b4f

"subcomponents": [
{ "@id": "pkg:golang/[email protected]" }
]
}
],
"status": "not_affected",
"justification": "vulnerable_code_not_in_execute_path"
}
]
```

It declares that `Module B` is not affected by CVE-XXXX-YYYY on `Module C`.

!!! note
The VEX in this example defines the relationship between `Module B` and `Module C`.
However, as Trivy traverses all parents from vulnerable packages, it is also possible to define a VEX for the relationship between a vulnerable package and any parent, such as `Module A` and `Module C`, etc.

Mapping this VEX onto the dependency tree would look like this:

```mermaid
graph TD;
modRootA(Module Root A v1.0.0)

subgraph "VEX (Not Affected)"
modB(Module B v1.0.0)
modC(Module C v2.0.0)
end

modRootA-->modB
modB-->modC
```

In this case, it's clear that `Module Root A` is also not affected by CVE-XXXX-YYYY, so this vulnerability is suppressed.

Now, let's consider another project:

```mermaid
graph TD;
modRootZ(Module Root Z v1.0.0)
modB'(Module B v1.0.0)
modC'(Module C v2.0.0)
modD'(Module D v3.0.0)

modRootZ-->modB'
modRootZ-->modD'
modB'-->modC'
modD'-->modC'
```

Assuming the same VEX as before, applying it to this dependency tree would look like:

```mermaid
graph TD;
modRootZ(Module Root Z v1.0.0)

subgraph "VEX (Not Affected)"
modB'(Module B v1.0.0)
modC'(Module C v2.0.0)
end

modD'(Module D v3.0.0)

modRootZ-->modB'
modRootZ-->modD'
modB'-->modC'
modD'-->modC'
```

`Module Root Z` depends on `Module C` via multiple paths.
While the VEX tells us that `Module B` is not affected by the vulnerability, `Module D` might be.
In the absence of a VEX, the default assumption is that it is affected.
Taking all of this into account, Trivy determines that `Module Root Z` is affected by this vulnerability.


[csaf]: https://oasis-open.github.io/csaf-documentation/specification.html
[openvex]: https://github.com/openvex/spec
Expand Down