From acbce05fbf4372a212a50a42f1032c1129e7e482 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 20 Jun 2014 06:47:46 -0400 Subject: [PATCH] updated to support suppression by maven coordinates (GAV) per issue #124 Former-commit-id: 3cff74ded9b0c352fb1d45e784d89c3c20f55467 --- .../suppression/SuppressionRule.java | 78 +++++++++++++++---- .../src/main/resources/schema/suppression.xsd | 1 + .../suppression/SuppressionRuleTest.java | 24 +++--- 3 files changed, 76 insertions(+), 27 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionRule.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionRule.java index b039cb3f4..a0e94f3f2 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionRule.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionRule.java @@ -234,6 +234,37 @@ public class SuppressionRule { public boolean hasCve() { return cve.size() > 0; } + /** + * A Maven GAV to suppression. + */ + private PropertyType gav = null; + + /** + * Get the value of Maven GAV. + * + * @return the value of gav + */ + public PropertyType getGav() { + return gav; + } + + /** + * Set the value of Maven GAV. + * + * @param gav new value of Maven gav + */ + public void setGav(PropertyType gav) { + this.gav = gav; + } + + /** + * Returns whether or not this suppression rule as GAV entries. + * + * @return whether or not this suppression rule as GAV entries + */ + public boolean hasGav() { + return gav != null; + } /** * Processes a given dependency to determine if any CPE, CVE, CWE, or CVSS scores should be suppressed. If any @@ -248,12 +279,27 @@ public class SuppressionRule { if (sha1 != null && !sha1.equalsIgnoreCase(dependency.getSha1sum())) { return; } + if (gav != null) { + final Iterator itr = dependency.getIdentifiers().iterator(); + boolean hasMatch = false; + while (itr.hasNext()) { + final Identifier i = itr.next(); + if (identifierMatches("maven", this.gav, i)) { + hasMatch = true; + break; + } + } + if (!hasMatch) { + return; + } + } + if (this.hasCpe()) { final Iterator itr = dependency.getIdentifiers().iterator(); while (itr.hasNext()) { final Identifier i = itr.next(); for (PropertyType c : this.cpe) { - if (cpeMatches(c, i)) { + if (identifierMatches("cpe", c, i)) { dependency.addSuppressedIdentifier(i); itr.remove(); break; @@ -336,23 +382,25 @@ public class SuppressionRule { /** * Determines if the cpeEntry specified as a PropertyType matches the given Identifier. * - * @param cpeEntry a suppression rule entry + * @param suppressionEntry a suppression rule entry * @param identifier a CPE identifier to check * @return true if the entry matches; otherwise false */ - boolean cpeMatches(PropertyType cpeEntry, Identifier identifier) { - if (cpeEntry.matches(identifier.getValue())) { - return true; - } else if (cpeHasNoVersion(cpeEntry)) { - if (cpeEntry.isCaseSensitive()) { - if (identifier.getValue().startsWith(cpeEntry.getValue())) { - return true; - } - } else { - final String id = identifier.getValue().toLowerCase(); - final String check = cpeEntry.getValue().toLowerCase(); - if (id.startsWith(check)) { - return true; + boolean identifierMatches(String identifierType, PropertyType suppressionEntry, Identifier identifier) { + if (identifierType.equals(identifier.getType())) { + if (suppressionEntry.matches(identifier.getValue())) { + return true; + } else if (cpeHasNoVersion(suppressionEntry)) { + if (suppressionEntry.isCaseSensitive()) { + if (identifier.getValue().startsWith(suppressionEntry.getValue())) { + return true; + } + } else { + final String id = identifier.getValue().toLowerCase(); + final String check = suppressionEntry.getValue().toLowerCase(); + if (id.startsWith(check)) { + return true; + } } } } diff --git a/dependency-check-core/src/main/resources/schema/suppression.xsd b/dependency-check-core/src/main/resources/schema/suppression.xsd index 14ae67a1a..083c8ae97 100644 --- a/dependency-check-core/src/main/resources/schema/suppression.xsd +++ b/dependency-check-core/src/main/resources/schema/suppression.xsd @@ -41,6 +41,7 @@ + diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionRuleTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionRuleTest.java index e1fdfb1d8..a5cfc3068 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionRuleTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionRuleTest.java @@ -339,7 +339,7 @@ public class SuppressionRuleTest { } /** - * Test of cpeMatches method, of class SuppressionRule. + * Test of identifierMatches method, of class SuppressionRule. */ @Test public void testCpeMatches() { @@ -350,44 +350,44 @@ public class SuppressionRuleTest { SuppressionRule instance = new SuppressionRule(); boolean expResult = true; - boolean result = instance.cpeMatches(cpe, identifier); + boolean result = instance.identifierMatches(cpe, identifier); assertEquals(expResult, result); cpe.setValue("cpe:/a:microsoft:.net_framework:4.0"); expResult = false; - result = instance.cpeMatches(cpe, identifier); + result = instance.identifierMatches(cpe, identifier); assertEquals(expResult, result); cpe.setValue("CPE:/a:microsoft:.net_framework:4.5"); cpe.setCaseSensitive(true); expResult = false; - result = instance.cpeMatches(cpe, identifier); + result = instance.identifierMatches(cpe, identifier); assertEquals(expResult, result); cpe.setValue("cpe:/a:microsoft:.net_framework"); cpe.setCaseSensitive(false); expResult = true; - result = instance.cpeMatches(cpe, identifier); + result = instance.identifierMatches(cpe, identifier); assertEquals(expResult, result); cpe.setValue("cpe:/a:microsoft:.*"); cpe.setRegex(true); expResult = true; - result = instance.cpeMatches(cpe, identifier); + result = instance.identifierMatches(cpe, identifier); assertEquals(expResult, result); cpe.setValue("CPE:/a:microsoft:.*"); cpe.setRegex(true); cpe.setCaseSensitive(true); expResult = false; - result = instance.cpeMatches(cpe, identifier); + result = instance.identifierMatches(cpe, identifier); assertEquals(expResult, result); cpe.setValue("cpe:/a:apache:.*"); cpe.setRegex(true); cpe.setCaseSensitive(false); expResult = false; - result = instance.cpeMatches(cpe, identifier); + result = instance.identifierMatches(cpe, identifier); assertEquals(expResult, result); } @@ -398,7 +398,7 @@ public class SuppressionRuleTest { public void testProcess() { File struts = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); Dependency dependency = new Dependency(struts); - dependency.addIdentifier("cwe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test"); + dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test"); String sha1 = dependency.getSha1sum(); dependency.setSha1sum("384FAA82E193D4E4B0546059CA09572654BC3970"); Vulnerability v = createVulnerability(); @@ -455,9 +455,9 @@ public class SuppressionRuleTest { assertTrue(dependency.getIdentifiers().isEmpty()); assertTrue(dependency.getSuppressedIdentifiers().size() == 1); - dependency.addIdentifier("cwe", "cpe:/a:microsoft:.net_framework:4.0", "some url not needed for this test"); - dependency.addIdentifier("cwe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test"); - dependency.addIdentifier("cwe", "cpe:/a:microsoft:.net_framework:5.0", "some url not needed for this test"); + dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:4.0", "some url not needed for this test"); + dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test"); + dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:5.0", "some url not needed for this test"); pt = new PropertyType(); pt.setValue("cpe:/a:microsoft:.net_framework"); instance.addCpe(pt);