Skip to content

Commit

Permalink
Merge pull request #4668 from nscuro/issue-4664
Browse files Browse the repository at this point in the history
  • Loading branch information
nscuro authored Feb 19, 2025
2 parents a19dba0 + d971ef9 commit 3ec9a98
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,11 @@ private void analyzePortfolio() {
break;
}

analyzeProject(qm, project, VulnerabilityAnalysisLevel.PERIODIC_ANALYSIS);
} catch (RuntimeException e) {
LOGGER.error("Failed to analyze project", e);
try {
analyzeProject(qm, project, VulnerabilityAnalysisLevel.PERIODIC_ANALYSIS);
} catch (RuntimeException e) {
LOGGER.error("Failed to analyze project", e);
}
} finally {
qm.getPersistenceManager().evictAll(false, Component.class);
qm.getPersistenceManager().evictAll(false, ComponentAnalysisCache.class);
Expand Down Expand Up @@ -199,9 +201,11 @@ private void analyzeProject(final UUID projectUuid, final VulnerabilityAnalysisL
var ignoredMdcProjectName = MDC.putCloseable(MDC_PROJECT_NAME, project.getName());
var ignoredMdcProjectVersion = MDC.putCloseable(MDC_PROJECT_VERSION, project.getVersion());
var ignoredMdcAnalysisLevel = MDC.putCloseable(MDC_VULN_ANALYSIS_LEVEL, analysisLevel.name())) {
analyzeProject(qm, project, analysisLevel);
} catch (RuntimeException e) {
LOGGER.error("Failed to analyze project", e);
try {
analyzeProject(qm, project, analysisLevel);
} catch (RuntimeException e) {
LOGGER.error("Failed to analyze project", e);
}
}
}
}
Expand Down Expand Up @@ -250,7 +254,13 @@ private void analyzeComponents(
}
}

qm.makeTransientAll(components);
// NB: Detaching components from this persistence manager so they can be used
// by PMs of analyzers. Components MUST NOT be made transient (QueryManager#makeTransientAll) here,
// as that would also dis-associate them from DataNucleus' state manager, preventing lazy-loading
// of other fields, should analyzers need them (e.g. component properties).
for (final Component component : components) {
qm.getPersistenceManager().detachCopy(component);
}

for (final ScanTask analyzer : analyzers) {
final List<Component> candidates = candidateComponentsByAnalyzerIdentity.get(analyzer.getAnalyzerIdentity());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,13 @@

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static java.util.Objects.requireNonNullElseGet;
import static org.dependencytrack.common.ConfigKey.TRIVY_RETRY_BACKOFF_INITIAL_DURATION_MS;
import static org.dependencytrack.common.ConfigKey.TRIVY_RETRY_BACKOFF_MAX_DURATION_MS;
import static org.dependencytrack.common.ConfigKey.TRIVY_RETRY_BACKOFF_MULTIPLIER;
Expand Down Expand Up @@ -251,8 +253,7 @@ public void analyze(final List<Component> components) {
}
}

for (final ComponentProperty property : component.getProperties()) {

for (final ComponentProperty property : requireNonNullElseGet(component.getProperties(), Collections::<ComponentProperty>emptyList)) {
if (property.getPropertyName().equals("trivy:SrcName")) {
srcName = property.getPropertyValue();
} else if (property.getPropertyName().equals("trivy:SrcVersion")) {
Expand Down Expand Up @@ -333,6 +334,12 @@ public void analyze(final List<Component> components) {

@Override
public boolean shouldAnalyze(final PackageURL packageUrl) {
if (packageUrl == null) {
// Components of classifier OPERATING_SYSTEM can "survive"
// the #isCapable call, despite not having a package URL.
return true;
}

return getApiBaseUrl()
.map(baseUrl -> !isCacheCurrent(Vulnerability.Source.TRIVY, apiBaseUrl, packageUrl.getCoordinates()))
.orElse(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@
import com.github.dockerjava.api.command.CreateVolumeResponse;
import com.github.dockerjava.api.model.Bind;
import org.dependencytrack.PersistenceCapableTest;
import org.dependencytrack.event.TrivyAnalysisEvent;
import org.dependencytrack.event.ProjectVulnerabilityAnalysisEvent;
import org.dependencytrack.model.Classifier;
import org.dependencytrack.model.Component;
import org.dependencytrack.model.Project;
import org.dependencytrack.model.Vulnerability;
import org.dependencytrack.model.VulnerabilityAnalysisLevel;
import org.dependencytrack.tasks.VulnerabilityAnalysisTask;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
Expand All @@ -44,7 +45,6 @@

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.dependencytrack.model.ConfigPropertyConstants.SCANNER_TRIVY_API_TOKEN;
Expand Down Expand Up @@ -157,9 +157,9 @@ public void test() {
componentA.setPurl("pkg:maven/com.fasterxml.woodstox/woodstox-core@5.0.0");
qm.persist(componentA);

final var analysisEvent = new TrivyAnalysisEvent(
List.of(componentA), VulnerabilityAnalysisLevel.BOM_UPLOAD_ANALYSIS);
new TrivyAnalysisTask().inform(analysisEvent);
final var analysisEvent = new ProjectVulnerabilityAnalysisEvent(
project, VulnerabilityAnalysisLevel.BOM_UPLOAD_ANALYSIS);
new VulnerabilityAnalysisTask().inform(analysisEvent);

assertThat(qm.getAllVulnerabilities(componentA)).anySatisfy(vuln -> {
assertThat(vuln.getVulnId()).isEqualTo("CVE-2022-40152");
Expand Down Expand Up @@ -248,9 +248,9 @@ public void testWithPackageWithoutTrivyProperties() {
component.setPurl("pkg:deb/ubuntu/libc6@2.35-0ubuntu3.4?arch=amd64&distro=ubuntu-22.04");
qm.persist(component);

final var analysisEvent = new TrivyAnalysisEvent(
List.of(osComponent, component), VulnerabilityAnalysisLevel.BOM_UPLOAD_ANALYSIS);
new TrivyAnalysisTask().inform(analysisEvent);
final var analysisEvent = new ProjectVulnerabilityAnalysisEvent(
project, VulnerabilityAnalysisLevel.BOM_UPLOAD_ANALYSIS);
new VulnerabilityAnalysisTask().inform(analysisEvent);

assertThat(qm.getAllVulnerabilities(component)).isEmpty();
}
Expand Down Expand Up @@ -329,9 +329,9 @@ public void testWithPackageWithTrivyProperties() {
qm.createComponentProperty(component, "aquasecurity", "trivy:PkgType", "ubuntu", IConfigProperty.PropertyType.STRING, null);


final var analysisEvent = new TrivyAnalysisEvent(
List.of(osComponent, component), VulnerabilityAnalysisLevel.BOM_UPLOAD_ANALYSIS);
new TrivyAnalysisTask().inform(analysisEvent);
final var analysisEvent = new ProjectVulnerabilityAnalysisEvent(
project, VulnerabilityAnalysisLevel.BOM_UPLOAD_ANALYSIS);
new VulnerabilityAnalysisTask().inform(analysisEvent);

assertThat(qm.getAllVulnerabilities(component)).anySatisfy(vuln -> {
assertThat(vuln.getVulnId()).isEqualTo("CVE-2016-20013");
Expand Down Expand Up @@ -421,9 +421,9 @@ public void testWithPackageWithTrivyPropertiesWithDistroWithoutOS() {
qm.createComponentProperty(component, "aquasecurity", "trivy:SrcName", "git", IConfigProperty.PropertyType.STRING, null);
qm.createComponentProperty(component, "aquasecurity", "trivy:SrcVersion", "2.43.0-r0", IConfigProperty.PropertyType.STRING, null);

final var analysisEvent = new TrivyAnalysisEvent(
List.of(osComponent, component), VulnerabilityAnalysisLevel.BOM_UPLOAD_ANALYSIS);
new TrivyAnalysisTask().inform(analysisEvent);
final var analysisEvent = new ProjectVulnerabilityAnalysisEvent(
project, VulnerabilityAnalysisLevel.BOM_UPLOAD_ANALYSIS);
new VulnerabilityAnalysisTask().inform(analysisEvent);

assertThat(qm.getAllVulnerabilities(component)).anySatisfy(vuln -> {
assertThat(vuln.getVulnId()).isEqualTo("CVE-2024-32002");
Expand Down Expand Up @@ -456,9 +456,9 @@ public void testWithGoPackage() {
component.setPurl("pkg:golang/github.com/nats-io/nkeys@0.4.4");
qm.persist(component);

final var analysisEvent = new TrivyAnalysisEvent(
List.of(component), VulnerabilityAnalysisLevel.BOM_UPLOAD_ANALYSIS);
new TrivyAnalysisTask().inform(analysisEvent);
final var analysisEvent = new ProjectVulnerabilityAnalysisEvent(
project, VulnerabilityAnalysisLevel.BOM_UPLOAD_ANALYSIS);
new VulnerabilityAnalysisTask().inform(analysisEvent);

assertThat(qm.getAllVulnerabilities(component)).hasSizeGreaterThanOrEqualTo(1);
}
Expand Down

0 comments on commit 3ec9a98

Please sign in to comment.