Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate Trivy integration to use Protobuf instead of JSON #4116

Merged
merged 1 commit into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading