Skip to content

Commit

Permalink
Use component name and version from PURL for Trivy analysis
Browse files Browse the repository at this point in the history
It turns out that `Component#version` differs from the PURL's version, in that it contains the epoch (e.g. `1:`). Trivy does not expect the epoch as part of the version field, since it has its own dedicated field.

For example:

```json
{
  "type": "library",
  "name": "dbus-common",
  "version": "1:1.12.20-8.el9",
  "purl": "pkg:rpm/redhat/[email protected]?arch=noarch&distro=redhat-9.4&epoch=1"
},
```

Signed-off-by: nscuro <[email protected]>
  • Loading branch information
nscuro committed Oct 15, 2024
1 parent c2a69ef commit a15c649
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import trivy.proto.common.OS;
import trivy.proto.common.Package;
import trivy.proto.common.PackageInfo;
import trivy.proto.common.PkgIdentifier;
import trivy.proto.scanner.v1.Result;
import trivy.proto.scanner.v1.ScanOptions;
import trivy.proto.scanner.v1.ScanResponse;
Expand Down Expand Up @@ -191,32 +192,33 @@ public void analyze(final List<Component> components) {
final var pkgs = new HashMap<String, PackageInfo.Builder>();
final var apps = new HashMap<String, Application.Builder>();
final var os = new HashMap<String, OS>();
final var map = new HashMap<String, Component>();
final var componentByPurl = new HashMap<String, Component>();

for (final Component component : components) {
if (component.getPurl() != null) {
var appType = PurlType.getApp(component.getPurl().getType());

var name = component.getName();
var name = component.getPurl().getName();

if (component.getGroup() != null) {
name = component.getGroup() + ":" + name;
if (component.getPurl().getNamespace() != null) {
name = component.getPurl().getNamespace() + ":" + name;
}

if (!PurlType.UNKNOWN.getAppType().equals(appType)) {
if (!PurlType.Constants.PACKAGES.equals(appType)) {
final Application.Builder app = apps.computeIfAbsent(appType, Application.newBuilder()::setType);
final String key = name + ":" + component.getVersion();
final String key = component.getPurl().toString();

LOGGER.debug("Add key %s to map".formatted(key));
map.put(key, component);
componentByPurl.put(key, component);

LOGGER.debug("add library %s".formatted(component.toString()));
app.addPackages(Package.newBuilder()
.setName(name)
.setVersion(component.getVersion())
.setVersion(component.getPurl().getVersion())
.setSrcName(name)
.setSrcVersion(component.getVersion()));
.setSrcVersion(component.getPurl().getVersion())
.setIdentifier(PkgIdentifier.newBuilder().setPurl(component.getPurl().toString())));
} else {
String srcName = null;
String srcVersion = null;
Expand All @@ -226,15 +228,13 @@ public void analyze(final List<Component> components) {
String pkgType = component.getPurl().getType();
String arch = null;
Integer epoch = null;
String versionKey = "";

if (component.getPurl().getQualifiers() != null) {
arch = component.getPurl().getQualifiers().get("arch");

String tmpEpoch = component.getPurl().getQualifiers().get("epoch");
if (tmpEpoch != null) {
epoch = Integer.parseInt(tmpEpoch);
versionKey = tmpEpoch + ":";
}

String distro = component.getPurl().getQualifiers().get("distro");
Expand Down Expand Up @@ -267,18 +267,18 @@ public void analyze(final List<Component> components) {

final PackageInfo.Builder pkg = pkgs.computeIfAbsent(pkgType, ignored -> PackageInfo.newBuilder());

versionKey += component.getVersion();
final String key = name + ":" + versionKey;
final String key = component.getPurl().toString();

LOGGER.debug("Add key %s to map".formatted(key));
map.put(key, component);
componentByPurl.put(key, component);
LOGGER.debug("add package %s".formatted(component.toString()));
final Package.Builder packageBuilder = Package.newBuilder()
.setName(component.getName())
.setVersion(component.getVersion())
.setName(component.getPurl().getName())
.setVersion(component.getPurl().getVersion())
.setArch(arch != null ? arch : "x86_64")
.setSrcName(srcName != null ? srcName : component.getName())
.setSrcVersion(srcVersion != null ? srcVersion : component.getVersion());
.setSrcName(srcName != null ? srcName : component.getPurl().getName())
.setSrcVersion(srcVersion != null ? srcVersion : component.getPurl().getVersion())
.setIdentifier(PkgIdentifier.newBuilder().setPurl(component.getPurl().toString()));
Optional.ofNullable(srcRelease).ifPresent(packageBuilder::setSrcRelease);
Optional.ofNullable(epoch).ifPresent(packageBuilder::setEpoch);
Optional.ofNullable(srcEpoch).ifPresent(packageBuilder::setSrcEpoch);
Expand Down Expand Up @@ -318,7 +318,7 @@ public void analyze(final List<Component> components) {

try {
final var results = analyzeBlob(infos);
handleResults(map, results);
handleResults(componentByPurl, results);
} catch (Throwable ex) {
handleRequestException(LOGGER, ex);
}
Expand All @@ -338,14 +338,14 @@ public void applyAnalysisFromCache(final Component component) {
component.getPurl().getCoordinates(), component, getAnalyzerIdentity(), vulnerabilityAnalysisLevel));
}

private void handleResults(final Map<String, Component> components, final ArrayList<Result> input) {
private void handleResults(final Map<String, Component> componentByPurl, final ArrayList<Result> input) {
for (final Result result : input) {
for (int idx = 0; idx < result.getVulnerabilitiesCount(); idx++) {
var vulnerability = result.getVulnerabilities(idx);
var key = vulnerability.getPkgName() + ":" + vulnerability.getInstalledVersion();
var key = vulnerability.getPkgIdentifier().getPurl();
LOGGER.debug("Searching key %s in map".formatted(key));
if (!super.isEnabled(ConfigPropertyConstants.SCANNER_TRIVY_IGNORE_UNFIXED) || vulnerability.getStatus() == 3) {
handle(components.get(key), vulnerability);
handle(componentByPurl.get(key), vulnerability);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ public void testAnalyzeWithRetry() throws ParseException {
.setVulnerabilityId("CVE-2022-40152")
.setPkgName("com.fasterxml.woodstox:woodstox-core")
.setPkgIdentifier(PkgIdentifier.newBuilder()
.setPurl("pkg:maven/com.fasterxml.woodstox/[email protected]")
.setPurl("pkg:maven/com.fasterxml.woodstox/[email protected]?foo=bar#baz")
.build())
.setInstalledVersion("5.0.0")
.setFixedVersion("6.4.0, 5.4.0")
Expand Down

0 comments on commit a15c649

Please sign in to comment.