[FEATURE]: Support multiple `analysis` element per `vulnerability`
Describe the problem
While writing a small proof-of-concept to show how VEX files can help downstream projects discard non exploitable vulnerability reports (copernik-eu/vexation I noticed a limitation of the current CycloneDX spec: each vulnerability object can have only one analysis element.
This means that we can only provide a single justification for all the affects elements, even if each "affects" may have a different justification.
Possible solutions
It might be a good idea to have multiple "analysis" elements and bind each of them with an "affects" element. This could allow to describe situation like:
- a VEX statement says that a CVE is not exploitable in component
a, since it is not exploitable in its dependencyb. The CycloneDX document could copy the analysis for componentb. - a VEX document could describe multiple versions. Some versions might depend on the vulnerable dependency, other might not. The analysis for each version could be different.
@ppkarwasz could you sketch a practical example in XML or JSON?
I was thinking about being able to publish "consolidated" <vulnerability> records that contain:
- The statement of the problem (in the example CVE-2022-25857) with a list of artifacts that contain the vulnerability (in the example
snakeyamland some application "Foo Server", because it bundles the vulnerable dependency). - A list of
analysisstatements from libraries that usesnakeyaml. Since these are libraries, they do not bundle the vulnerable dependency, these statements should be read as:If my application contains a package mentioned in
vulnerability.affects(anywhere in the dependency tree) and I also have a direct dependency mentioned invulnerability.analysis.affects, then I need to read the analysis to see the impact of the vulnerability on my application
<vulnerability bom-ref="CVE-2022-25857">
<id>CVE-2022-25857</id>
<description>
Using SnakeYAML to parse untrusted YAML files may be vulnerable to Denial of Service attacks (DOS).
SnakeYAML versions before 1.31 are vulnerable to Denial of Service (DoS) due missing to nested depth limitation
for collections.
</description>
<recommendation>
Users that parse untrusted YAML files should upgrade to version 1.31 or later.
</recommendation>
<affects>
<target>
<ref>pkg:maven/org.yaml/snakeyaml</ref>
<versions>
<version>
<range>vers:maven/<1.31</range>
<status>affected</status>
</version>
</versions>
</target>
<target>
<ref>Foo Server</ref>
<versions>
<version>
<range>vers:maven/<1.2.3</range>
<status>affected</status>
</version>
</versions>
</target>
</affects>
<analyses>
<analysis>
<state>affected</state>
<detail>
This vulnerability is exploitable in `jackson-dataformat-yaml` if:
* `snakeyaml` before 1.31 is used.
* `jackson-dataformat-yaml` is used to parse untrusted YAML files.
Versions of `jackson-dataformat-yaml` prior to 2.5 do not use SnakeYAML and are therefore unaffected.
Since version 2.13.4 of `jackson-dataformat-yaml` the recommended `snakeyaml` version is 1.31 or higher,
therefore it is not affected by default.
Users of versions between 2.5 and 2.13.4 are recommended to manually pin their `snakeyaml` version to 1.31 or
higher.
</detail>
<affects>
<target>
<ref>pkg:maven/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml</ref>
<versions>
<version>
<range>vers:maven/<2.5</range>
<status>unaffected</status>
</version>
<version>
<range>vers:maven/>=2.5|<2.13.4</range>
<status>affected</status>
</version>
<version>
<range>vers:maven/>=2.13.4</range>
<status>unknown</status>
</version>
</versions>
</target>
</affects>
</analysis>
<analysis>
<state>not_affected</state>
<justification>workaround_available</justification>
<detail>
Log4j Core only uses the YAML parser for configuration files. According to our
[threat model](https://logging.apache.org/security.html#threat-common), it is up to the users to ensure that
configuration files come from trusted sources.
Therefore, this CVE does not affect Log4j Core.
</detail>
<affects>
<target>
<ref>pkg:maven/org.apache.logging.log4j/log4j-core</ref>
<versions>
<version>
<range>vers:maven/>=2.0</range>
<status>unaffected</status>
</version>
</versions>
</target>
</affects>
</analysis>
<analyses>
</vulnerability>
@pombredanne, do you have any suggestions?