Skip to content

Commit 2100be7

Browse files
jeremylongCopilotchadlwilsonnhumblot
authored
feat: package and utilize generated suppression file (#8116)
Co-authored-by: Copilot <[email protected]> Co-authored-by: Chad Wilson <[email protected]> Co-authored-by: Nicolas Humblot <[email protected]>
1 parent 6c4d2ef commit 2100be7

File tree

3 files changed

+65
-34
lines changed

3 files changed

+65
-34
lines changed

core/pom.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,24 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
100100
</testResource>
101101
</testResources>
102102
<plugins>
103+
<plugin>
104+
<groupId>io.github.download-maven-plugin</groupId>
105+
<artifactId>download-maven-plugin</artifactId>
106+
<executions>
107+
<execution>
108+
<id>download-published-suppressions</id>
109+
<phase>generate-resources</phase>
110+
<goals>
111+
<goal>wget</goal>
112+
</goals>
113+
<configuration>
114+
<url>https://dependency-check.github.io/DependencyCheck/suppressions/publishedSuppressions.xml</url>
115+
<outputDirectory>${project.build.directory}/classes</outputDirectory>
116+
<outputFileName>dependencycheck-hosted-suppression-snapshot.xml</outputFileName>
117+
</configuration>
118+
</execution>
119+
</executions>
120+
</plugin>
103121
<plugin>
104122
<groupId>org.jsonschema2pojo</groupId>
105123
<artifactId>jsonschema2pojo-maven-plugin</artifactId>

core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import java.util.Set;
3131
import java.util.regex.Pattern;
3232
import javax.annotation.concurrent.ThreadSafe;
33+
34+
import org.jetbrains.annotations.NotNull;
3335
import org.owasp.dependencycheck.Engine;
3436
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
3537
import org.owasp.dependencycheck.data.update.HostedSuppressionsDataSource;
@@ -68,6 +70,10 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
6870
* The file name of the base suppression XML file.
6971
*/
7072
private static final String BASE_SUPPRESSION_FILE = "dependencycheck-base-suppression.xml";
73+
/**
74+
* The file name of the snapshot of the hosted suppression XML file.
75+
*/
76+
private static final String HOSTED_SUPPRESSION_SNAPSHOT_FILE = "dependencycheck-hosted-suppression-snapshot.xml";
7177
/**
7278
* The key used to store and retrieve the suppression files.
7379
*/
@@ -188,32 +194,16 @@ private void loadSuppressionBaseData(final Engine engine) throws SuppressionPars
188194
}
189195

190196
/**
191-
* Loads the base suppression rules packaged with the application.
197+
* Loads the suppression rules packaged with the application.
192198
*
193199
* @param parser The suppression parser to use
194200
* @param engine a reference the dependency-check engine
195201
* @throws SuppressionParseException thrown if the XML cannot be parsed.
196202
*/
197203
private void loadPackagedSuppressionBaseData(final SuppressionParser parser, final Engine engine) throws SuppressionParseException {
198204
List<SuppressionRule> ruleList = null;
199-
final URL jarLocation = AbstractSuppressionAnalyzer.class.getProtectionDomain().getCodeSource().getLocation();
200-
String suppressionFileLocation = jarLocation.getFile();
201-
if (suppressionFileLocation.endsWith(".jar")) {
202-
suppressionFileLocation = "jar:file:" + suppressionFileLocation + "!/" + BASE_SUPPRESSION_FILE;
203-
} else if (suppressionFileLocation.startsWith("nested:") && suppressionFileLocation.endsWith(".jar!/")) {
204-
// suppressionFileLocation -> nested:/app/app.jar/!BOOT-INF/lib/dependency-check-core-<version>.jar!/
205-
// goal-> jar:nested:/app/app.jar/!BOOT-INF/lib/dependency-check-core-<version>.jar!/dependencycheck-base-suppression.xml
206-
suppressionFileLocation = "jar:" + suppressionFileLocation + BASE_SUPPRESSION_FILE;
207-
} else {
208-
suppressionFileLocation = "file:" + suppressionFileLocation + BASE_SUPPRESSION_FILE;
209-
}
210-
URL baseSuppresssionURL = null;
211-
try {
212-
baseSuppresssionURL = new URL(suppressionFileLocation);
213-
} catch (MalformedURLException e) {
214-
throw new SuppressionParseException("Unable to load the base suppression data file", e);
215-
}
216-
try (InputStream in = baseSuppresssionURL.openStream()) {
205+
URL baseSuppressionURL = getPackagedFile(BASE_SUPPRESSION_FILE);
206+
try (InputStream in = baseSuppressionURL.openStream()) {
217207
ruleList = parser.parseSuppressionRules(in);
218208
} catch (SAXException | IOException ex) {
219209
throw new SuppressionParseException("Unable to parse the base suppression data file", ex);
@@ -229,6 +219,27 @@ private void loadPackagedSuppressionBaseData(final SuppressionParser parser, fin
229219
}
230220
}
231221

222+
private static @NotNull URL getPackagedFile(String packagedFileName) throws SuppressionParseException {
223+
final URL jarLocation = AbstractSuppressionAnalyzer.class.getProtectionDomain().getCodeSource().getLocation();
224+
String suppressionFileLocation = jarLocation.getFile();
225+
if (suppressionFileLocation.endsWith(".jar")) {
226+
suppressionFileLocation = "jar:file:" + suppressionFileLocation + "!/" + packagedFileName;
227+
} else if (suppressionFileLocation.startsWith("nested:") && suppressionFileLocation.endsWith(".jar!/")) {
228+
// suppressionFileLocation -> nested:/app/app.jar/!BOOT-INF/lib/dependency-check-core-<version>.jar!/
229+
// goal-> jar:nested:/app/app.jar/!BOOT-INF/lib/dependency-check-core-<version>.jar!/dependencycheck-base-suppression.xml
230+
suppressionFileLocation = "jar:" + suppressionFileLocation + packagedFileName;
231+
} else {
232+
suppressionFileLocation = "file:" + suppressionFileLocation + packagedFileName;
233+
}
234+
URL baseSuppressionURL = null;
235+
try {
236+
baseSuppressionURL = new URL(suppressionFileLocation);
237+
} catch (MalformedURLException e) {
238+
throw new SuppressionParseException("Unable to load the packaged file: " + packagedFileName, e);
239+
}
240+
return baseSuppressionURL;
241+
}
242+
232243
/**
233244
* Loads all the base suppression rules from the hosted suppression file
234245
* generated/updated automatically by the FP Suppression GitHub Action for
@@ -242,31 +253,28 @@ private void loadPackagedSuppressionBaseData(final SuppressionParser parser, fin
242253
* @param parser The suppression parser to use
243254
*/
244255
private void loadHostedSuppressionBaseData(final SuppressionParser parser, final Engine engine) {
245-
final File repoFile;
246-
boolean repoEmpty = false;
247256
final boolean enabled = getSettings().getBoolean(Settings.KEYS.HOSTED_SUPPRESSIONS_ENABLED, true);
248257
if (!enabled) {
249258
return;
250259
}
251-
final boolean autoupdate = getSettings().getBoolean(Settings.KEYS.AUTO_UPDATE, true);
252-
final boolean forceupdate = getSettings().getBoolean(Settings.KEYS.HOSTED_SUPPRESSIONS_FORCEUPDATE, false);
253260

254261
try {
255262
final String configuredUrl = getSettings().getString(Settings.KEYS.HOSTED_SUPPRESSIONS_URL,
256263
HostedSuppressionsDataSource.DEFAULT_SUPPRESSIONS_URL);
257264
final URL url = new URL(configuredUrl);
258265
final String fileName = new File(url.getPath()).getName();
259-
repoFile = new File(getSettings().getDataDirectory(), fileName);
260-
if (!repoFile.isFile() || repoFile.length() <= 1L) {
261-
repoEmpty = true;
262-
LOGGER.warn("Hosted Suppressions file is empty or missing - attempting to force the update");
263-
getSettings().setBoolean(Settings.KEYS.HOSTED_SUPPRESSIONS_FORCEUPDATE, true);
264-
}
265-
if ((!autoupdate && forceupdate) || (autoupdate && repoEmpty)) {
266-
if (engine == null) {
267-
LOGGER.warn("Engine was null, this should only happen in tests - skipping forced update");
268-
} else {
269-
repoEmpty = forceUpdateHostedSuppressions(engine, repoFile);
266+
final File repoFile = new File(getSettings().getDataDirectory(), fileName);
267+
boolean repoEmpty = !repoFile.isFile() || repoFile.length() <= 1L;
268+
if (repoEmpty) {
269+
// utilize the snapshot hosted suppression file
270+
URL hostedSuppressionSnapshotURL = getPackagedFile(HOSTED_SUPPRESSION_SNAPSHOT_FILE);
271+
try (InputStream in = hostedSuppressionSnapshotURL.openStream()) {
272+
Files.copy(in, repoFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
273+
repoEmpty = false;
274+
LOGGER.debug("Copied hosted suppression snapshot file to {}", repoFile.toPath());
275+
} catch (IOException ex) {
276+
LOGGER.warn("Unable to copy the hosted suppression snapshot file to {}, results may contain false positives "
277+
+ "already resolved by the DependencyCheck project", repoFile.toPath(), ex);
270278
}
271279
}
272280
if (!repoEmpty) {

pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,11 @@ Copyright (c) 2012 - Jeremy Long
187187
<defaultGoal>clean install</defaultGoal>
188188
<pluginManagement>
189189
<plugins>
190+
<plugin>
191+
<groupId>io.github.download-maven-plugin</groupId>
192+
<artifactId>download-maven-plugin</artifactId>
193+
<version>2.0.0</version>
194+
</plugin>
190195
<plugin>
191196
<groupId>org.jsonschema2pojo</groupId>
192197
<artifactId>jsonschema2pojo-maven-plugin</artifactId>

0 commit comments

Comments
 (0)