Skip to content

TrivyAnalysisTask: URL-encoding confusion between OS component and and PURL of library component #5216

@MarkusGeigerDev

Description

@MarkusGeigerDev

Current Behavior

A BOM generated with trivy image --format cyclonedx --output sbom.json amazoncorretto:21.0.7 will result in no vulnerbilities found when uploaded to DT although there are (at the time of writing) 3 CVEs known.

Steps to Reproduce

  1. generate an SBOM with trivy image --format cyclonedx --output result.cdx amazoncorretto:21.0.7 OR use this minimal example: minimal.json

  2. upload SBOM into a project in DT

Expected Behavior

At the time of writing, at least 3 CVEs should have been reported for the full SBOM, two of them are from libxml, which is included as an example in the minimal SBOM attached above.

Dependency-Track Version

4.13.3

Dependency-Track Distribution

Container Image

Database Server

PostgreSQL

Database Server Version

16

Browser

Microsoft Edge

Checklist

My analysis up to this point:

Assume the minimal example attached above: This SBOM has two components: one component with the category operating_system, the name amazon and the version 2 (Karoo) and another component (a library) with the PURL pkg:rpm/amazon/[email protected]?arch=x86_64&distro=amazon-2+%28Karoo%29".

This code

} else if (component.getClassifier() == Classifier.OPERATING_SYSTEM) {
LOGGER.debug("add operative system %s".formatted(component.toString()));
var key = "%s-%s".formatted(component.getName(), component.getVersion());
os.put(key, OS.newBuilder().setFamily(component.getName()).setName(component.getVersion()).build());
}

adds an OS with the key "amazon-2 (Karoo)", but later this code
LOGGER.debug("looking for os %s".formatted(key));
if (os.get(key) != null) {
builder.setOs(os.get(key));
}

will fail to find the OS because the "distro" part of the PURL is "amazon-2+%28Karoo%29". As a result, the lookup of the operating system in the OS map fails and the library component is sent to Trivy without an OS. This means that Trivy cannot analyze the component.

Maybe using an URL-encoded version of the OS string as the key would help?

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
// ...
} else if (component.getClassifier() == Classifier.OPERATING_SYSTEM) {
    LOGGER.debug("add operative system %s".formatted(component.toString()));
    var key = URLEncoder.encode("%s-%s".formatted(component.getName(), component.getVersion()), StandardCharsets.UTF_8);
    os.put(key, OS.newBuilder().setFamily(component.getName()).setName(component.getVersion()).build());
}
// ...
String distro = component.getPurl().getQualifiers().get("distro");
if (os.get(distro) != null) {
    builder.setOs(os.get(distro));
}

Cross check: Manually editing the SBOM to remove everything after the digit "2" in both, the OS component's version and the library's component PURL's "distro" part, will result in an SBOM that works just fine.

Metadata

Metadata

Assignees

No one assigned

    Labels

    defectSomething isn't workingintegration/trivyRelated to the Trivy integrationp2Non-critical bugs, and features that help organizations to identify and reduce risksize/SSmall effort

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions