diff --git a/ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskIT.java b/ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskIT.java index 6c0128e312b..4e65118ce0e 100644 --- a/ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskIT.java +++ b/ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskIT.java @@ -29,6 +29,7 @@ import org.owasp.dependencycheck.BaseDBTestCase; import static org.junit.Assert.assertTrue; +import org.owasp.dependencycheck.xml.suppression.SuppressionRules; /** * @@ -131,8 +132,8 @@ public void testNestedBADReportFormat() throws Exception { public void testGetFailBuildOnCVSS() { Exception exception = Assert.assertThrows(BuildException.class, () -> buildFileRule.executeTarget("failCVSS")); - String expectedMessage = String.format("One or more dependencies were identified with vulnerabilities that " + - "have a CVSS score greater than or equal to '%.1f':", 3.0f); + String expectedMessage = String.format("One or more dependencies were identified with vulnerabilities that " + + "have a CVSS score greater than or equal to '%.1f':", 3.0f); Assert.assertTrue(exception.getMessage().contains(expectedMessage)); } @@ -144,7 +145,8 @@ public void testGetFailBuildOnCVSS() { public void testSuppressingCVE() { // GIVEN an ant task with a vulnerability final String antTaskName = "suppression"; - + //as the suppression rules are now a singleton - we must reset the list to cause the new suppression rules to load + SuppressionRules.getInstance().list().clear(); // WHEN executing the ant task buildFileRule.executeTarget(antTaskName); if (buildFileRule.getError() != null && !buildFileRule.getError().isEmpty()) { @@ -168,7 +170,8 @@ public void testSuppressingCVE() { public void testSuppressingSingle() { // GIVEN an ant task with a vulnerability using the legacy property final String antTaskName = "suppression-single"; - + //as the suppression rules are now a singleton - we must reset the list to cause the new suppression rules to load + SuppressionRules.getInstance().list().clear(); // WHEN executing the ant task buildFileRule.executeTarget(antTaskName); @@ -185,7 +188,8 @@ public void testSuppressingSingle() { public void testSuppressingMultiple() { // GIVEN an ant task with a vulnerability using multiple was to configure the suppression file final String antTaskName = "suppression-multiple"; - + //as the suppression rules are now a singleton - we must reset the list to cause the new suppression rules to load + SuppressionRules.getInstance().list().clear(); // WHEN executing the ant task buildFileRule.executeTarget(antTaskName); diff --git a/core/src/main/java/org/owasp/dependencycheck/Engine.java b/core/src/main/java/org/owasp/dependencycheck/Engine.java index b6c6e9e1148..5fbf2ea0070 100644 --- a/core/src/main/java/org/owasp/dependencycheck/Engine.java +++ b/core/src/main/java/org/owasp/dependencycheck/Engine.java @@ -82,6 +82,7 @@ import static org.owasp.dependencycheck.analyzer.AnalysisPhase.PRE_IDENTIFIER_ANALYSIS; import static org.owasp.dependencycheck.analyzer.AnalysisPhase.PRE_INFORMATION_COLLECTION; import org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer; +import org.owasp.dependencycheck.xml.suppression.SuppressionRules; /** * Scans files, directories, etc. for Dependencies. Analyzers are loaded and @@ -659,6 +660,8 @@ public void analyzeDependencies() throws ExceptionCollection { .map(analyzers::get) .forEach((analyzerList) -> analyzerList.forEach(this::closeAnalyzer)); + SuppressionRules.getInstance().logUnusedRules(); + LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------"); final long analysisDurationSeconds = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - analysisStart); LOGGER.info("Analysis Complete ({} seconds)", analysisDurationSeconds); diff --git a/core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java b/core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java index a6e8d4ed48c..d5c2ed3a8af 100644 --- a/core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java +++ b/core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java @@ -43,7 +43,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; -import org.owasp.dependencycheck.xml.suppression.SuppressionRuleFilter; +import org.owasp.dependencycheck.xml.suppression.SuppressionRules; /** * Abstract base suppression analyzer that contains methods for parsing the @@ -52,7 +52,7 @@ * @author Jeremy Long */ @ThreadSafe -public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer implements SuppressionRuleFilter { +public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { /** * The Logger for use throughout the class. @@ -63,9 +63,18 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer imple */ private static final String BASE_SUPPRESSION_FILE = "dependencycheck-base-suppression.xml"; /** - * The list of suppression rules. + * The collection of suppression rules. */ - private final List rules = new ArrayList<>(); + private final SuppressionRules rules = SuppressionRules.getInstance(); + + /** + * Returns the suppression rules. + * + * @return the suppression rules + */ + protected SuppressionRules getSuppressionRules() { + return rules; + } /** * Get the number of suppression rules. @@ -114,9 +123,22 @@ protected void analyzeDependency(Dependency dependency, Engine engine) throws An if (rules.isEmpty()) { return; } - rules.forEach((rule) -> rule.process(dependency)); + for (SuppressionRule rule : rules.list()) { + if (filter(rule)) { + rule.process(dependency); + } + } } + /** + * Determines whether a suppression rule should be retained when filtering a set of suppression rules for a concrete suppression analyzer. + * + * @param rule the suppression rule to evaluate + * @return true if the rule should be retained; otherwise + * false + */ + abstract boolean filter(SuppressionRule rule); + /** * Loads all the suppression rules files configured in the {@link Settings}. * @@ -160,7 +182,7 @@ private void loadSuppressionBaseData() throws SuppressionParseException { if (in == null) { throw new SuppressionParseException("Suppression rules `" + BASE_SUPPRESSION_FILE + "` could not be found"); } - ruleList = parser.parseSuppressionRules(in, this); + ruleList = parser.parseSuppressionRules(in); } catch (SAXException | IOException ex) { throw new SuppressionParseException("Unable to parse the base suppression data file", ex); } @@ -235,7 +257,7 @@ private List loadSuppressionFile(final SuppressionParser parser throw new SuppressionParseException(msg); } try { - list.addAll(parser.parseSuppressionRules(file, this)); + list.addAll(parser.parseSuppressionRules(file)); } catch (SuppressionParseException ex) { LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath()); LOGGER.warn(ex.getMessage()); diff --git a/core/src/main/java/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzer.java b/core/src/main/java/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzer.java index d021df5edcf..2d9a9291a74 100644 --- a/core/src/main/java/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzer.java +++ b/core/src/main/java/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzer.java @@ -82,7 +82,7 @@ protected String getAnalyzerEnabledSettingKey() { @Override public boolean filter(SuppressionRule rule) { - return !rule.hasCpe(); + return rule.hasCpe(); } @Override diff --git a/core/src/main/java/org/owasp/dependencycheck/analyzer/VulnerabilitySuppressionAnalyzer.java b/core/src/main/java/org/owasp/dependencycheck/analyzer/VulnerabilitySuppressionAnalyzer.java index 830cef39f60..8f4ddc786e5 100644 --- a/core/src/main/java/org/owasp/dependencycheck/analyzer/VulnerabilitySuppressionAnalyzer.java +++ b/core/src/main/java/org/owasp/dependencycheck/analyzer/VulnerabilitySuppressionAnalyzer.java @@ -76,7 +76,7 @@ protected String getAnalyzerEnabledSettingKey() { @Override public boolean filter(SuppressionRule rule) { - return !(rule.hasCve() || rule.hasCvssBelow() || rule.hasCwe() || rule.hasVulnerabilityName()); + return rule.hasCve() || rule.hasCvssBelow() || rule.hasCwe() || rule.hasVulnerabilityName(); } @Override diff --git a/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.java b/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.java index 359bb3ef2ed..3ea7aebbf3c 100644 --- a/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.java +++ b/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.java @@ -104,10 +104,6 @@ public class SuppressionHandler extends DefaultHandler { * The current node text being extracted from the element. */ private StringBuilder currentText; - /** - * The suppression rule filter. - */ - private final SuppressionRuleFilter filter; /** * Get the value of suppressionRules. @@ -118,17 +114,6 @@ public List getSuppressionRules() { return suppressionRules; } - /** - * Constructs a Suppression Handler. - * - * @param filter The suppression rule filter used when loading the - * suppression rules. This is used to differentiate vulnerability - * suppression rules from CPE suppression rules. - */ - public SuppressionHandler(SuppressionRuleFilter filter) { - this.filter = filter; - } - /** * Handles the start element event. * @@ -176,8 +161,6 @@ public void endElement(String uri, String localName, String qName) throws SAXExc case SUPPRESS: if (rule.getUntil() != null && rule.getUntil().before(Calendar.getInstance())) { LOGGER.info("Suppression is expired for rule: {}", rule); - } else if (filter != null && filter.filter(rule)) { - LOGGER.debug("Filtering {} for {}", rule.toString(), filter.getName()); } else { suppressionRules.add(rule); } diff --git a/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionParser.java b/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionParser.java index a4866cf2f68..17e19fe1871 100644 --- a/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionParser.java +++ b/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionParser.java @@ -77,14 +77,13 @@ public class SuppressionParser { * contained. * * @param file an XML file containing suppression rules - * @param filter the suppression rule filter * @return a list of suppression rules * @throws SuppressionParseException thrown if the XML file cannot be parsed */ @SuppressFBWarnings(justification = "try with resource will clenaup the resources", value = {"OBL_UNSATISFIED_OBLIGATION"}) - public List parseSuppressionRules(File file, SuppressionRuleFilter filter) throws SuppressionParseException { + public List parseSuppressionRules(File file) throws SuppressionParseException { try (FileInputStream fis = new FileInputStream(file)) { - return parseSuppressionRules(fis, filter); + return parseSuppressionRules(fis); } catch (SAXException | IOException ex) { LOGGER.debug("", ex); throw new SuppressionParseException(ex); @@ -96,12 +95,11 @@ public List parseSuppressionRules(File file, SuppressionRuleFil * contained. * * @param inputStream an InputStream containing suppression rules - * @param filter a filter to use when loading suppression rules * @return a list of suppression rules * @throws SuppressionParseException thrown if the XML cannot be parsed * @throws SAXException thrown if the XML cannot be parsed */ - public List parseSuppressionRules(InputStream inputStream, SuppressionRuleFilter filter) + public List parseSuppressionRules(InputStream inputStream) throws SuppressionParseException, SAXException { try ( InputStream schemaStream13 = FileUtils.getResourceAsStream(SUPPRESSION_SCHEMA_1_3); @@ -114,7 +112,7 @@ public List parseSuppressionRules(InputStream inputStream, Supp final String defaultEncoding = StandardCharsets.UTF_8.name(); final String charsetName = bom == null ? defaultEncoding : bom.getCharsetName(); - final SuppressionHandler handler = new SuppressionHandler(filter); + final SuppressionHandler handler = new SuppressionHandler(); final SAXParser saxParser = XmlUtils.buildSecureSaxParser(schemaStream13, schemaStream12, schemaStream11, schemaStream10); final XMLReader xmlReader = saxParser.getXMLReader(); xmlReader.setErrorHandler(new SuppressionErrorHandler()); diff --git a/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRule.java b/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRule.java index 5643517dfa9..3fd508ab05e 100644 --- a/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRule.java +++ b/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRule.java @@ -103,6 +103,29 @@ public class SuppressionRule { */ private Calendar until; + /** + * A flag whether or not the rule matched a dependency & CPE. + */ + private boolean matched = false; + + /** + * Get the value of matched. + * + * @return the value of matched + */ + public boolean isMatched() { + return matched; + } + + /** + * Set the value of matched. + * + * @param matched new value of matched + */ + public void setMatched(boolean matched) { + this.matched = matched; + } + /** * Get the (@code{nullable}) value of until. * @@ -467,6 +490,7 @@ public void process(Dependency dependency) { for (PropertyType c : this.cpe) { if (identifierMatches(c, i)) { if (!isBase()) { + matched = true; if (this.notes != null) { i.setNotes(this.notes); } @@ -507,7 +531,6 @@ public void process(Dependency dependency) { removeVulns.add(v); break; } - } } if (!remove) { @@ -524,13 +547,12 @@ public void process(Dependency dependency) { } } } - if (remove) { - if (!isBase()) { - if (this.notes != null) { - v.setNotes(this.notes); - } - dependency.addSuppressedVulnerability(v); + if (remove && !isBase()) { + matched = true; + if (this.notes != null) { + v.setNotes(this.notes); } + dependency.addSuppressedVulnerability(v); } } removeVulns.forEach(dependency::removeVulnerability); @@ -644,6 +666,9 @@ public String toString() { if (sha1 != null) { sb.append("sha1=").append(sha1).append(','); } + if (packageUrl != null) { + sb.append("packageUrl=").append(packageUrl).append(','); + } if (gav != null) { sb.append("gav=").append(gav).append(','); } diff --git a/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRuleFilter.java b/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRuleFilter.java deleted file mode 100644 index 01607c7fc97..00000000000 --- a/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRuleFilter.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of dependency-check-core. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright (c) 2021 Jeremy Long. All Rights Reserved. - */ -package org.owasp.dependencycheck.xml.suppression; - -/** - * A simple suppression rule filter. - * - * @author Jeremy Long - */ -public interface SuppressionRuleFilter { - - /** - * Determines whether or not to filter a suppression rule. - * - * @param rule the suppression rule to evaluate - * @return true if the rule should be filtered; otherwise - * true - */ - boolean filter(SuppressionRule rule); - - /** - * Returns the name of the filter. - * - * @return the name of the filters - */ - String getName(); -} diff --git a/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRules.java b/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRules.java new file mode 100644 index 00000000000..9010e96f43b --- /dev/null +++ b/core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRules.java @@ -0,0 +1,104 @@ +/* + * This file is part of dependency-check-core. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (c) 2022 Jeremy Long. All Rights Reserved. + */ +package org.owasp.dependencycheck.xml.suppression; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import java.util.ArrayList; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Jeremy Long + */ +public final class SuppressionRules { + + /** + * Singleton. + */ + private static final SuppressionRules INSTANCE = new SuppressionRules(); + /** + * The Logger for use throughout the class. + */ + private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionRules.class); + /** + * The list of suppression RULES. + */ + private static final List RULES = new ArrayList<>(); + + private SuppressionRules() { + } + + /** + * Returns the instance of SuppressionRules. + * + * @return the instance of SuppressionRules + */ + @SuppressFBWarnings(justification = "Intended", value = {"MS_EXPOSE_REP"}) + public static SuppressionRules getInstance() { + return INSTANCE; + } + + /** + * Get the number of suppression RULES. + * + * @return the number of suppression RULES + */ + public int size() { + return RULES.size(); + } + + /** + * Returns true if there are no suppression RULES; otherwise false. + * + * @return true if there are no suppression RULES; otherwise false + */ + public boolean isEmpty() { + return RULES.isEmpty(); + } + + /** + * Returns the list of suppression RULES. + * + * @return the list of suppression RULES + */ + public List list() { + return RULES; + } + + /** + * Appends the new suppression RULES to the list of RULES. + * + * @param newRules the new suppression RULES + */ + public void addAll(List newRules) { + RULES.addAll(newRules); + } + + /** + * Logs unused suppression RULES. + */ + public void logUnusedRules() { + RULES.forEach((rule) -> { + if (!rule.isMatched() && !rule.isBase()) { + LOGGER.debug("Suppression Rule had zero matches: {}", rule.toString()); + } + }); + } +} diff --git a/core/src/test/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.java b/core/src/test/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.java index 34ed15f36c4..29d5b2e8042 100644 --- a/core/src/test/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.java +++ b/core/src/test/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.java @@ -34,6 +34,7 @@ import org.owasp.dependencycheck.utils.Settings; import org.owasp.dependencycheck.utils.Settings.KEYS; import org.owasp.dependencycheck.xml.suppression.SuppressionRule; +import org.owasp.dependencycheck.xml.suppression.SuppressionRules; /** * @author Jeremy Long @@ -49,11 +50,12 @@ public class AbstractSuppressionAnalyzerTest extends BaseTest { * Suppression file to test with. */ private static final String SUPPRESSIONS_FILE = "suppressions.xml"; - + private AbstractSuppressionAnalyzer instance; - + @Before public void createObjectUnderTest() throws Exception { + SuppressionRules.getInstance().list().clear(); instance = new AbstractSuppressionAnalyzerImpl(); } @@ -112,7 +114,7 @@ public void testGetRulesFromMultipleSuppressionFiles() throws Exception { final int expectedSize = rulesInFirstFile + rulesInSecondFile + rulesInCoreFile; assertThat("Expected suppressions from both files", instance.getRuleCount(), is(expectedSize)); } - + @Test(expected = InitializationException.class) public void testFailureToLocateSuppressionFileAnywhere() throws Exception { getSettings().setString(Settings.KEYS.SUPPRESSION_FILE, "doesnotexist.xml"); @@ -132,7 +134,9 @@ private int getNumberOfRulesLoadedInCoreFile() throws Exception { final AbstractSuppressionAnalyzerImpl coreFileAnalyzer = new AbstractSuppressionAnalyzerImpl(); coreFileAnalyzer.initialize(getSettings()); coreFileAnalyzer.prepare(null); - return coreFileAnalyzer.getRuleCount(); + int count = coreFileAnalyzer.getRuleCount(); + coreFileAnalyzer.reset(); + return count; } /** @@ -148,26 +152,28 @@ private int getNumberOfRulesLoadedFromPath(final String path) throws Exception { final AbstractSuppressionAnalyzerImpl fileAnalyzer = new AbstractSuppressionAnalyzerImpl(); fileAnalyzer.initialize(getSettings()); fileAnalyzer.prepare(null); - return fileAnalyzer.getRuleCount(); + int count = fileAnalyzer.getRuleCount(); + fileAnalyzer.reset(); + return count; } - + public static class AbstractSuppressionAnalyzerImpl extends AbstractSuppressionAnalyzer { - + @Override public void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } - + @Override public String getName() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } - + @Override public AnalysisPhase getAnalysisPhase() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } - + @Override protected String getAnalyzerEnabledSettingKey() { return "unknown"; @@ -177,6 +183,10 @@ protected String getAnalyzerEnabledSettingKey() { public boolean filter(SuppressionRule rule) { return false; } + + public void reset() { + getSuppressionRules().list().clear(); + } } - + } diff --git a/core/src/test/java/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzerIT.java b/core/src/test/java/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzerIT.java index f447b94ca03..71fd0e9fca3 100644 --- a/core/src/test/java/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzerIT.java +++ b/core/src/test/java/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzerIT.java @@ -26,6 +26,7 @@ import org.owasp.dependencycheck.utils.Settings; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import org.owasp.dependencycheck.xml.suppression.SuppressionRules; /** * Testing the CPE suppression analyzer. @@ -63,10 +64,9 @@ public void testGetAnalysisPhase() { */ @Test public void testAnalyze() throws Exception { - - //File file = new File(this.getClass().getClassLoader().getResource("commons-fileupload-1.2.1.jar").getPath()); + //as the suppression rules are now a singleton - we must reset the list to cause the new suppression rules to load + SuppressionRules.getInstance().list().clear(); File file = BaseTest.getResourceAsFile(this, "commons-fileupload-1.2.1.jar"); - //File suppression = new File(this.getClass().getClassLoader().getResource("commons-fileupload-1.2.1.suppression.xml").getPath()); File suppression = BaseTest.getResourceAsFile(this, "commons-fileupload-1.2.1.suppression.xml"); getSettings().setBoolean(Settings.KEYS.AUTO_UPDATE, false); getSettings().setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); @@ -79,18 +79,20 @@ public void testAnalyze() throws Exception { int cpeSize = dependency.getVulnerableSoftwareIdentifiers().size(); assertTrue(cveSize > 0); assertTrue(cpeSize > 0); + //as the suppression rules are now a singleton - we must reset the list to cause the new suppression rules to load + SuppressionRules.getInstance().list().clear(); getSettings().setString(Settings.KEYS.SUPPRESSION_FILE, suppression.getAbsolutePath()); CpeSuppressionAnalyzer instance = new CpeSuppressionAnalyzer(); instance.initialize(getSettings()); instance.prepare(engine); instance.analyze(dependency, engine); - //after adding filtering to the load - the cpe suppression - //analyzer no longer suppresses CPEs. - //cveSize -= 1; + cpeSize -= 1; assertEquals(cveSize, dependency.getVulnerabilities().size()); assertEquals(cpeSize, dependency.getVulnerableSoftwareIdentifiers().size()); } + //be kind to other tests and cleanup any custom loaded suppression rules for your test. + SuppressionRules.getInstance().list().clear(); } /** diff --git a/core/src/test/java/org/owasp/dependencycheck/analyzer/VulnerabilitySuppressionAnalyzerIT.java b/core/src/test/java/org/owasp/dependencycheck/analyzer/VulnerabilitySuppressionAnalyzerIT.java index 3706afb26ba..6162276befe 100644 --- a/core/src/test/java/org/owasp/dependencycheck/analyzer/VulnerabilitySuppressionAnalyzerIT.java +++ b/core/src/test/java/org/owasp/dependencycheck/analyzer/VulnerabilitySuppressionAnalyzerIT.java @@ -26,6 +26,7 @@ import org.owasp.dependencycheck.utils.Settings; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import org.owasp.dependencycheck.xml.suppression.SuppressionRules; /** * Testing the vulnerability suppression analyzer. @@ -64,15 +65,17 @@ public void testGetAnalysisPhase() { */ @Test public void testAnalyze() throws Exception { + //as the suppression rules are now a singleton - we must reset the list to cause the new suppression rules to load + SuppressionRules.getInstance().list().clear(); - //File file = new File(this.getClass().getClassLoader().getResource("commons-fileupload-1.2.1.jar").getPath()); File file = BaseTest.getResourceAsFile(this, "commons-fileupload-1.2.1.jar"); - //File suppression = new File(this.getClass().getClassLoader().getResource("commons-fileupload-1.2.1.suppression.xml").getPath()); File suppression = BaseTest.getResourceAsFile(this, "commons-fileupload-1.2.1.suppression.xml"); getSettings().setBoolean(Settings.KEYS.AUTO_UPDATE, false); getSettings().setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); getSettings().setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); try (Engine engine = new Engine(getSettings())) { + //as the suppression rules are now a singleton - we must reset the list to cause the new suppression rules to load + SuppressionRules.getInstance().list().clear(); engine.scan(file); engine.analyzeDependencies(); Dependency dependency = getDependency(engine, file); @@ -81,6 +84,8 @@ public void testAnalyze() throws Exception { assertTrue(cveSize > 0); assertTrue(cpeSize > 0); getSettings().setString(Settings.KEYS.SUPPRESSION_FILE, suppression.getAbsolutePath()); + //as the suppression rules are now a singleton - we must reset the list to cause the new suppression rules to load + SuppressionRules.getInstance().list().clear(); VulnerabilitySuppressionAnalyzer instance = new VulnerabilitySuppressionAnalyzer(); instance.initialize(getSettings()); instance.prepare(engine); @@ -92,6 +97,8 @@ public void testAnalyze() throws Exception { assertEquals(cveSize, dependency.getVulnerabilities().size()); assertEquals(cpeSize, dependency.getVulnerableSoftwareIdentifiers().size()); } + //be kind to other tests and cleanup any custom loaded suppression rules for your test. + SuppressionRules.getInstance().list().clear(); } /** diff --git a/core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIT.java b/core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIT.java index b55591fbfee..bbe87171305 100644 --- a/core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIT.java +++ b/core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIT.java @@ -44,6 +44,7 @@ import org.owasp.dependencycheck.data.update.exception.UpdateException; import org.owasp.dependencycheck.dependency.Dependency; import org.owasp.dependencycheck.utils.DownloadFailedException; +import org.owasp.dependencycheck.xml.suppression.SuppressionRules; /** * @@ -75,6 +76,9 @@ public void testGenerateReport() { settings.setBoolean(Settings.KEYS.PRETTY_PRINT, true); generateReport(settings, writeTo, writeJsonTo, writeHtmlTo, writeJunitTo, writeCsvTo, writeSarifTo, suppressionFile); + + //be kind to other tests and cleanup any custom loaded suppression rules for your test. + SuppressionRules.getInstance().list().clear(); } /** @@ -100,6 +104,8 @@ public void testGenerateNodeAuditReport() { settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); generateReport(settings, writeTo, writeJsonTo, writeHtmlTo, writeJunitTo, writeCsvTo, writeSarifTo, suppressionFile); + //be kind to other tests and cleanup any custom loaded suppression rules for your test. + SuppressionRules.getInstance().list().clear(); } @@ -126,6 +132,8 @@ public void testGenerateRetireJsReport() { settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); generateReport(settings, writeTo, writeJsonTo, writeHtmlTo, writeJunitTo, writeCsvTo, writeSarifTo, suppressionFile); + //be kind to other tests and cleanup any custom loaded suppression rules for your test. + SuppressionRules.getInstance().list().clear(); } /** * Generates an XML report containing known vulnerabilities and realistic @@ -150,6 +158,8 @@ public void testGenerateNodePackageReport() { settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); generateReport(settings, writeTo, writeJsonTo, writeHtmlTo, writeJunitTo, writeCsvTo, writeSarifTo, suppressionFile); + //be kind to other tests and cleanup any custom loaded suppression rules for your test. + SuppressionRules.getInstance().list().clear(); } diff --git a/core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandlerTest.java b/core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandlerTest.java index e678fd3dd67..f304112eff3 100644 --- a/core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandlerTest.java +++ b/core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandlerTest.java @@ -48,7 +48,7 @@ public void testHandler() throws Exception { File file = BaseTest.getResourceAsFile(this, "suppressions.xml"); InputStream schemaStream = BaseTest.getResourceAsStream(this, "schema/suppression.xsd"); - SuppressionHandler handler = new SuppressionHandler(null); + SuppressionHandler handler = new SuppressionHandler(); SAXParser saxParser = XmlUtils.buildSecureSaxParser(schemaStream); XMLReader xmlReader = saxParser.getXMLReader(); xmlReader.setErrorHandler(new SuppressionErrorHandler()); diff --git a/core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionParserTest.java b/core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionParserTest.java index a0a4f3b7e1a..106b00e170e 100644 --- a/core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionParserTest.java +++ b/core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionParserTest.java @@ -40,7 +40,7 @@ public void testParseSuppressionRulesV1dot0() throws Exception { //File file = new File(this.getClass().getClassLoader().getResource("suppressions.xml").getPath()); File file = BaseTest.getResourceAsFile(this, "suppressions.xml"); SuppressionParser instance = new SuppressionParser(); - List result = instance.parseSuppressionRules(file, null); + List result = instance.parseSuppressionRules(file); Assert.assertEquals(5, result.size()); } @@ -53,7 +53,7 @@ public void testParseSuppressionRulesV1dot1() throws Exception { //File file = new File(this.getClass().getClassLoader().getResource("suppressions.xml").getPath()); File file = BaseTest.getResourceAsFile(this, "suppressions_1_1.xml"); SuppressionParser instance = new SuppressionParser(); - List result = instance.parseSuppressionRules(file, null); + List result = instance.parseSuppressionRules(file); Assert.assertEquals(5, result.size()); } @@ -66,7 +66,7 @@ public void testParseSuppressionRulesV1dot2() throws Exception { //File file = new File(this.getClass().getClassLoader().getResource("suppressions.xml").getPath()); File file = BaseTest.getResourceAsFile(this, "suppressions_1_2.xml"); SuppressionParser instance = new SuppressionParser(); - List result = instance.parseSuppressionRules(file, null); + List result = instance.parseSuppressionRules(file); Assert.assertEquals(4, result.size()); } @@ -79,7 +79,7 @@ public void testParseSuppressionRulesV1dot3() throws Exception { //File file = new File(this.getClass().getClassLoader().getResource("suppressions.xml").getPath()); File file = BaseTest.getResourceAsFile(this, "suppressions_1_3.xml"); SuppressionParser instance = new SuppressionParser(); - List result = instance.parseSuppressionRules(file, null); + List result = instance.parseSuppressionRules(file); Assert.assertEquals(4, result.size()); } }