Skip to content

Commit

Permalink
Add functionality to suppress CVEs in upload goal (pmckeown#423)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Pepryk committed Nov 27, 2024
1 parent 398bded commit 0482893
Show file tree
Hide file tree
Showing 16 changed files with 742 additions and 447 deletions.
61 changes: 61 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,67 @@ Example:
</execution>
```

#### Suppress Vulnerabilities

You can also suppress certain vulnerabilities in the XML configuration, if you believe that they don't affect the project
and can't be exploited. The suppression will be applied during the upload of the BOM and thus won't taken into account
for other goals following the upload. This way goals like `findings` or `metrics` won't fail because of the suppressed
vulnerabilities, if they are configured to do so.

You can enter a list of vulnerabilities to be suppressed like so:

**XML Configuration Example**
```xml
<configuration>
<suppressions>
<suppression>
<cve>CVE-2022-41853</cve>
<state>NOT_AFFECTED</state>
<justification>CODE_NOT_REACHABLE</justification>
<details>Test dependency</details>
</suppression>
<suppression>
<cve>CVE-2021-42392</cve>
</suppression>
</suppressions>
</configuration>
```

| Property | Required | Default Value |
|---------------------------|----------|---------------|
| suppression | false | N/A |
| suppression.cve | true | N/A |
| suppression.state | false | NOT_AFFECTED |
| suppression.justification | false | NOT_SET |
| suppression.details | false | N/A |

All possible values for state are:

* NOT_AFFECTED
* FALSE_POSITIVE
* IN_TRIAGE
* EXPLOITABLE
* NOT_SET
* RESOLVED

All possible values for justification are:

* CODE_NOT_PRESENT
* CODE_NOT_REACHABLE
* REQUIRES_CONFIGURATION
* REQUIRES_DEPENDENCY
* REQUIRES_ENVIRONMENT
* PROTECTED_BY_COMPILER
* PROTECTED_AT_RUNTIME
* PROTECTED_AT_PERIMETER
* PROTECTED_BY_MITIGATING_CONTROL
* NOT_SET

**Notes:**
* The configured vulnerabilities will always be suppressed at the Dependency Track server regardless of the state.
* The justification can only have another value than NOT_SET when the state is set to NOT_AFFECTED. Otherwise the
justification defaults back to NOT_SET.

### Get Project Findings
After a BOM upload, the best way to determine if there are any vulnerabilities is to use the `findings` goal which is
usable immediately after an upload. Other goals, such as `metrics` and `score` pull down information from the
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.9.1.2184</version>
<version>9.1.2184</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
*/
public final class ResourceConstants {

public static final String V1_BOM = "/api/v1/bom";
public static final String V1_ANALYSIS = "/api/v1/analysis";
public static final String V1_BOM = "/api/v1/bom";
public static final String V1_BOM_TOKEN_UUID = "/api/v1/bom/token/{uuid}";
public static final String V1_PROJECT_LOOKUP = "/api/v1/project/lookup";
public static final String V1_PROJECT_UUID = "/api/v1/project/{uuid}";
Expand All @@ -16,7 +17,7 @@ public final class ResourceConstants {
public static final String V1_METRICS_PROJECT_UUID_REFRESH = "/api/v1/metrics/project/{uuid}/refresh";
public static final String V1_POLICY_VIOLATION_PROJECT_UUID = "/api/v1/violation/project/{uuid}";

private ResourceConstants() {
// Constants file
}
private ResourceConstants() {
// Constants file
}
}
Original file line number Diff line number Diff line change
@@ -1,43 +1,67 @@
package io.github.pmckeown.dependencytrack.finding;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.xml.bind.annotation.XmlElement;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import javax.xml.bind.annotation.XmlElement;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class Analysis {

public enum State {
NOT_AFFECTED,
FALSE_POSITIVE,
IN_TRIAGE,
EXPLOITABLE,
NOT_SET
}

private boolean isSuppressed;
private State state;

@JsonCreator
public Analysis(@JsonProperty("isSuppressed") boolean isSuppressed, @JsonProperty("state") State state) {
this.isSuppressed = isSuppressed;
this.state = state;
}

@XmlElement
public boolean isSuppressed() {
return isSuppressed;
}

@XmlElement
public State getState() {
return state;
}

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
}
public enum AnalysisState {
NOT_AFFECTED,
FALSE_POSITIVE,
IN_TRIAGE,
EXPLOITABLE,
NOT_SET,
RESOLVED
}

public enum AnalysisJustification {
CODE_NOT_PRESENT,
CODE_NOT_REACHABLE,
REQUIRES_CONFIGURATION,
REQUIRES_DEPENDENCY,
REQUIRES_ENVIRONMENT,
PROTECTED_BY_COMPILER,
PROTECTED_AT_RUNTIME,
PROTECTED_AT_PERIMETER,
PROTECTED_BY_MITIGATING_CONTROL,
NOT_SET
}

private boolean isSuppressed;
private AnalysisState analysisState;
private AnalysisJustification analysisJustification;

@JsonCreator
public Analysis(@JsonProperty("isSuppressed") final boolean isSuppressed,
@JsonProperty("analysisState") final AnalysisState analysisState,
@JsonProperty("analysisJustification") final AnalysisJustification analysisJustification) {
this.isSuppressed = isSuppressed;
this.analysisState = analysisState;
this.analysisJustification = analysisJustification;
}

@XmlElement
public boolean isSuppressed() {
return isSuppressed;
}

@XmlElement
public AnalysisState getAnalysisState() {
return analysisState;
}

@XmlElement
public AnalysisJustification getAnalysisJustification() {
return analysisJustification;
}

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package io.github.pmckeown.dependencytrack.finding;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import io.github.pmckeown.dependencytrack.finding.Analysis.AnalysisJustification;
import io.github.pmckeown.dependencytrack.finding.Analysis.AnalysisState;

public class AnalysisDecisionRequest {

/*
* For project, component and vulnerability the according UUID must be used
*/
private String project;
private String component;
private String vulnerability;
private AnalysisState analysisState;
private AnalysisJustification analysisJustification;
private String analysisDetails;
private boolean isSuppressed;

public AnalysisDecisionRequest(final String project, final String component, final String vulnerability,
final AnalysisState analysisState, final AnalysisJustification analysisJustification,
final String analysisDetails, final boolean isSuppressed) {
this.project = project;
this.component = component;
this.vulnerability = vulnerability;
this.analysisState = analysisState;
this.isSuppressed = isSuppressed;
this.analysisJustification = analysisJustification;
this.analysisDetails = analysisDetails;
}

public String getProject() {
return project;
}

public String getComponent() {
return component;
}

public String getVulnerability() {
return vulnerability;
}

public AnalysisState getAnalysisState() {
return analysisState;
}

public AnalysisJustification getAnalysisJustification() {
return analysisJustification;
}

public String getAnalysisDetails() {
return analysisDetails;
}

public boolean isSuppressed() {
return isSuppressed;
}

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
}
}
Loading

0 comments on commit 0482893

Please sign in to comment.