Skip to content

Commit 63eb85a

Browse files
authored
docs: explain how VEX is applied (#6864)
Signed-off-by: knqyf263 <knqyf263@gmail.com>
1 parent 1e2db83 commit 63eb85a

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

docs/docs/supply-chain/vex.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,8 @@ $ trivy image ghcr.io/aquasecurity/trivy:0.50.0 --vex trivy.openvex.json
263263
VEX documents can indeed be reused across different container images, eliminating the need to issue separate VEX documents for each image.
264264
This is particularly useful when there is a common component or library that is used across multiple projects or container images.
265265

266+
You can see [the appendix](#applying-vex-to-dependency-trees) for more details on how VEX is applied in Trivy.
267+
266268
### Scan with VEX
267269
Provide the VEX when scanning your target.
268270

@@ -412,6 +414,8 @@ At present, the specified relationship category is not taken into account and al
412414
- installed_on
413415
- installed_with
414416

417+
You can see [the appendix](#applying-vex-to-dependency-trees) for more details on how VEX is applied in Trivy.
418+
415419
### Scan with CSAF VEX
416420
Provide the CSAF document when scanning your target.
417421

@@ -470,6 +474,103 @@ does not match:
470474
- `pkg:maven/com.google.guava/guava@24.1.1?classifier=sources`
471475
- `classifier` must have the same value.
472476

477+
### Applying VEX to Dependency Trees
478+
479+
Trivy internally generates a dependency tree and applies VEX statements to this graph.
480+
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:
481+
482+
```mermaid
483+
graph TD;
484+
modRootA(Module Root A v1.0.0)
485+
modB(Module B v1.0.0)
486+
modC(Module C v2.0.0)
487+
488+
modRootA-->modB
489+
modB-->modC
490+
```
491+
492+
Now, suppose a VEX statement is issued for `Module B` as follows:
493+
494+
```json
495+
"statements": [
496+
{
497+
"vulnerability": {"name": "CVE-XXXX-YYYY"},
498+
"products": [
499+
{
500+
"@id": "pkg:golang/module-b@1.0.0",
501+
"subcomponents": [
502+
{ "@id": "pkg:golang/module-c@2.0.0" }
503+
]
504+
}
505+
],
506+
"status": "not_affected",
507+
"justification": "vulnerable_code_not_in_execute_path"
508+
}
509+
]
510+
```
511+
512+
It declares that `Module B` is not affected by CVE-XXXX-YYYY on `Module C`.
513+
514+
!!! note
515+
The VEX in this example defines the relationship between `Module B` and `Module C`.
516+
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.
517+
518+
Mapping this VEX onto the dependency tree would look like this:
519+
520+
```mermaid
521+
graph TD;
522+
modRootA(Module Root A v1.0.0)
523+
524+
subgraph "VEX (Not Affected)"
525+
modB(Module B v1.0.0)
526+
modC(Module C v2.0.0)
527+
end
528+
529+
modRootA-->modB
530+
modB-->modC
531+
```
532+
533+
In this case, it's clear that `Module Root A` is also not affected by CVE-XXXX-YYYY, so this vulnerability is suppressed.
534+
535+
Now, let's consider another project:
536+
537+
```mermaid
538+
graph TD;
539+
modRootZ(Module Root Z v1.0.0)
540+
modB'(Module B v1.0.0)
541+
modC'(Module C v2.0.0)
542+
modD'(Module D v3.0.0)
543+
544+
modRootZ-->modB'
545+
modRootZ-->modD'
546+
modB'-->modC'
547+
modD'-->modC'
548+
```
549+
550+
Assuming the same VEX as before, applying it to this dependency tree would look like:
551+
552+
```mermaid
553+
graph TD;
554+
modRootZ(Module Root Z v1.0.0)
555+
556+
subgraph "VEX (Not Affected)"
557+
modB'(Module B v1.0.0)
558+
modC'(Module C v2.0.0)
559+
end
560+
561+
modD'(Module D v3.0.0)
562+
563+
modRootZ-->modB'
564+
modRootZ-->modD'
565+
modB'-->modC'
566+
modD'-->modC'
567+
```
568+
569+
`Module Root Z` depends on `Module C` via multiple paths.
570+
While the VEX tells us that `Module B` is not affected by the vulnerability, `Module D` might be.
571+
In the absence of a VEX, the default assumption is that it is affected.
572+
Taking all of this into account, Trivy determines that `Module Root Z` is affected by this vulnerability.
573+
473574

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

0 commit comments

Comments
 (0)