Skip to content

Commit

Permalink
Merge pull request #4116 from nscuro/issue-4065
Browse files Browse the repository at this point in the history
Migrate Trivy integration to use Protobuf instead of JSON
  • Loading branch information
nscuro authored Sep 2, 2024
2 parents e672e6b + af64eef commit 114c6d6
Show file tree
Hide file tree
Showing 23 changed files with 691 additions and 1,158 deletions.
2 changes: 2 additions & 0 deletions docs/_posts/2024-xx-xx-v4.12.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type: major
* Disable redundant shutdown hook of the embedded H2 database - [apiserver/#4106]
* Support inclusion and exclusion of projects from BOM validation with tags - [apiserver/#4109]
* Update Dependency-Track's own BOM to CycloneDX v1.5 - [apiserver/#4110]
* Migrate Trivy integration to use Protobuf instead of JSON - [apiserver/#4116]
* Support for serving the frontend from a custom path - [frontend/#801]
* Add dynamic policy violation badges - [frontend/#810]
* Add quick search for projects also using a component - [frontend/#848]
Expand Down Expand Up @@ -142,6 +143,7 @@ Special thanks to everyone who contributed code to implement enhancements and fi
[apiserver/#4108]: https://github.com/DependencyTrack/dependency-track/pull/4108
[apiserver/#4109]: https://github.com/DependencyTrack/dependency-track/pull/4109
[apiserver/#4110]: https://github.com/DependencyTrack/dependency-track/pull/4110
[apiserver/#4116]: https://github.com/DependencyTrack/dependency-track/pull/4116

[frontend/#801]: https://github.com/DependencyTrack/frontend/pull/801
[frontend/#810]: https://github.com/DependencyTrack/frontend/pull/810
Expand Down
41 changes: 41 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
<lib.open-vulnerability-clients.version>6.2.0</lib.open-vulnerability-clients.version>
<lib.packageurl.version>1.5.0</lib.packageurl.version>
<lib.pebble.version>3.2.2</lib.pebble.version>
<lib.protobuf-java.version>4.28.0</lib.protobuf-java.version>
<lib.resilience4j.version>2.2.0</lib.resilience4j.version>
<lib.swagger-parser.version>2.1.22</lib.swagger-parser.version>
<lib.system-rules.version>1.19.0</lib.system-rules.version>
Expand All @@ -139,8 +140,11 @@
<plugin.cyclonedx.outputFormat>json</plugin.cyclonedx.outputFormat>
<plugin.retirejs.breakOnFailure>false</plugin.retirejs.breakOnFailure>
<plugin.jetty.version>12.0.12</plugin.jetty.version>
<plugin.protoc-jar.version>3.11.4</plugin.protoc-jar.version>
<!-- SonarCloud properties -->
<sonar.exclusions>src/main/webapp/**</sonar.exclusions>
<!-- Tool Versions -->
<tool.protoc.version>com.google.protobuf:protoc:${lib.protobuf-java.version}</tool.protoc.version>
<!-- CycloneDX CLI -->
<cyclonedx-cli.path>cyclonedx</cyclonedx-cli.path>
<services.bom.merge.skip>true</services.bom.merge.skip>
Expand Down Expand Up @@ -203,6 +207,7 @@
<artifactId>cyclonedx-core-java</artifactId>
<version>${lib.cyclonedx-java.version}</version>
</dependency>

<!-- org.json
This was previously transitively included with Unirest. However, Unirest v3.x removed reliance on org.json
in favor of their own API compatible replacement. Therefore, it was necessary to directly include org.json.
Expand Down Expand Up @@ -263,6 +268,17 @@
<version>${lib.pebble.version}</version>
</dependency>

<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${lib.protobuf-java.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>${lib.protobuf-java.version}</version>
</dependency>

<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-jaxrs2-jakarta</artifactId>
Expand Down Expand Up @@ -561,6 +577,30 @@
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>com.github.os72</groupId>
<artifactId>protoc-jar-maven-plugin</artifactId>
<version>${plugin.protoc-jar.version}</version>
<executions>
<execution>
<id>protobuf</id>
<phase>generate-sources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<includeMavenTypes>direct</includeMavenTypes>
<inputDirectories>
<inputDirectory>src/main/proto</inputDirectory>
</inputDirectories>
<includeDirectories>
<includeDirectory>src/main/proto</includeDirectory>
</includeDirectories>
<protocArtifact>${tool.protoc.version}</protocArtifact>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
Expand All @@ -586,6 +626,7 @@
<configuration>
<excludes>
<exclude>org/dependencytrack/upgrade/**/*</exclude>
<exclude>trivy/proto/**/*</exclude>
</excludes>
</configuration>
</plugin>
Expand Down
69 changes: 22 additions & 47 deletions src/main/java/org/dependencytrack/parser/trivy/TrivyParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,89 +18,64 @@
*/
package org.dependencytrack.parser.trivy;

import alpine.common.logging.Logger;
import com.google.protobuf.util.Timestamps;
import org.dependencytrack.model.Cwe;
import org.dependencytrack.model.Severity;
import org.dependencytrack.model.Vulnerability;
import org.dependencytrack.parser.common.resolver.CweResolver;
import org.dependencytrack.parser.trivy.model.CVSS;
import trivy.proto.common.CVSS;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.List;

import static org.apache.commons.lang3.StringUtils.trimToNull;

public class TrivyParser {

private static final Logger LOGGER = Logger.getLogger(TrivyParser.class);

public Vulnerability parse(org.dependencytrack.parser.trivy.model.Vulnerability data) {
public Vulnerability parse(trivy.proto.common.Vulnerability data) {
var vulnerability = new Vulnerability();
vulnerability.setSource(Vulnerability.Source.resolve(data.getVulnerabilityID()));
vulnerability.setSource(Vulnerability.Source.resolve(data.getVulnerabilityId()));
vulnerability.setPatchedVersions(data.getFixedVersion());

// get the id of the data record (vulnerability)
vulnerability.setVulnId(data.getVulnerabilityID());
vulnerability.setVulnId(data.getVulnerabilityId());
vulnerability.setTitle(data.getTitle());
vulnerability.setDescription(data.getDescription());
vulnerability.setSeverity(parseSeverity(data.getSeverity()));

try {
vulnerability.setPublished(parseDate(data.getPublishedDate()));
if (data.hasPublishedDate()) {
vulnerability.setPublished(new Date(Timestamps.toMillis(data.getPublishedDate())));
vulnerability.setCreated(vulnerability.getPublished());
} catch (ParseException ex) {
LOGGER.warn("Unable to parse published date %s".formatted(data.getPublishedDate()), ex);
}

try {
vulnerability.setUpdated(parseDate(data.getLastModifiedDate()));
} catch (ParseException ex) {
LOGGER.warn("Unable to parse last modified date %s".formatted(data.getLastModifiedDate()), ex);
if (data.hasLastModifiedDate()) {
vulnerability.setUpdated(new Date(Timestamps.toMillis(data.getLastModifiedDate())));
}

vulnerability.setReferences(addReferences(data.getReferences()));
vulnerability.setReferences(addReferences(data.getReferencesList()));

// CWE
for (String id : data.getCweIDS()) {
for (String id : data.getCweIdsList()) {
final Cwe cwe = CweResolver.getInstance().lookup(id);
if (cwe != null) {
vulnerability.addCwe(cwe);
}
}

vulnerability = setCvssScore(data.getCvss().get(data.getSeveritySource()), vulnerability);
vulnerability = setCvssScore(data.getCvssMap().get(data.getSeveritySource()), vulnerability);

return vulnerability;
}

public Date parseDate(String input) throws ParseException {
if (input != null) {
String format = input.length() == 20 ? "yyyy-MM-dd'T'HH:mm:ss'Z'" : "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
SimpleDateFormat formatter = new SimpleDateFormat(format, Locale.ENGLISH);
return formatter.parse(input);
}
return null;
}

public Severity parseSeverity(String severity) {

if (severity != null) {
if (severity.equalsIgnoreCase("CRITICAL")) {
return Severity.CRITICAL;
} else if (severity.equalsIgnoreCase("HIGH")) {
return Severity.HIGH;
} else if (severity.equalsIgnoreCase("MEDIUM")) {
return Severity.MEDIUM;
} else if (severity.equalsIgnoreCase("LOW")) {
return Severity.LOW;
} else {
return Severity.UNASSIGNED;
}
}
return Severity.UNASSIGNED;
public Severity parseSeverity(trivy.proto.common.Severity severity) {
return switch (severity) {
case CRITICAL -> Severity.CRITICAL;
case HIGH -> Severity.HIGH;
case MEDIUM -> Severity.MEDIUM;
case LOW -> Severity.LOW;
default -> Severity.UNASSIGNED;
};
}

public Vulnerability setCvssScore(CVSS cvss, Vulnerability vulnerability) {
Expand All @@ -118,7 +93,7 @@ public Vulnerability setCvssScore(CVSS cvss, Vulnerability vulnerability) {
return vulnerability;
}

public String addReferences(String[] references) {
public String addReferences(List<String> references) {
final StringBuilder sb = new StringBuilder();
for (String reference : references) {
if (reference != null) {
Expand Down

This file was deleted.

47 changes: 0 additions & 47 deletions src/main/java/org/dependencytrack/parser/trivy/model/BlobInfo.java

This file was deleted.

44 changes: 0 additions & 44 deletions src/main/java/org/dependencytrack/parser/trivy/model/CVSS.java

This file was deleted.

Loading

0 comments on commit 114c6d6

Please sign in to comment.