updated to support suppression by maven coordinates (GAV) per issue #124

Former-commit-id: 3cff74ded9b0c352fb1d45e784d89c3c20f55467
This commit is contained in:
Jeremy Long
2014-06-20 06:47:46 -04:00
parent bee4d3a338
commit acbce05fbf
3 changed files with 76 additions and 27 deletions

View File

@@ -234,6 +234,37 @@ public class SuppressionRule {
public boolean hasCve() { public boolean hasCve() {
return cve.size() > 0; 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 * 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())) { if (sha1 != null && !sha1.equalsIgnoreCase(dependency.getSha1sum())) {
return; return;
} }
if (gav != null) {
final Iterator<Identifier> 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()) { if (this.hasCpe()) {
final Iterator<Identifier> itr = dependency.getIdentifiers().iterator(); final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
while (itr.hasNext()) { while (itr.hasNext()) {
final Identifier i = itr.next(); final Identifier i = itr.next();
for (PropertyType c : this.cpe) { for (PropertyType c : this.cpe) {
if (cpeMatches(c, i)) { if (identifierMatches("cpe", c, i)) {
dependency.addSuppressedIdentifier(i); dependency.addSuppressedIdentifier(i);
itr.remove(); itr.remove();
break; break;
@@ -336,23 +382,25 @@ public class SuppressionRule {
/** /**
* Determines if the cpeEntry specified as a PropertyType matches the given Identifier. * 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 * @param identifier a CPE identifier to check
* @return true if the entry matches; otherwise false * @return true if the entry matches; otherwise false
*/ */
boolean cpeMatches(PropertyType cpeEntry, Identifier identifier) { boolean identifierMatches(String identifierType, PropertyType suppressionEntry, Identifier identifier) {
if (cpeEntry.matches(identifier.getValue())) { if (identifierType.equals(identifier.getType())) {
return true; if (suppressionEntry.matches(identifier.getValue())) {
} else if (cpeHasNoVersion(cpeEntry)) { return true;
if (cpeEntry.isCaseSensitive()) { } else if (cpeHasNoVersion(suppressionEntry)) {
if (identifier.getValue().startsWith(cpeEntry.getValue())) { if (suppressionEntry.isCaseSensitive()) {
return true; if (identifier.getValue().startsWith(suppressionEntry.getValue())) {
} return true;
} else { }
final String id = identifier.getValue().toLowerCase(); } else {
final String check = cpeEntry.getValue().toLowerCase(); final String id = identifier.getValue().toLowerCase();
if (id.startsWith(check)) { final String check = suppressionEntry.getValue().toLowerCase();
return true; if (id.startsWith(check)) {
return true;
}
} }
} }
} }

View File

@@ -41,6 +41,7 @@
<xs:choice minOccurs="0" maxOccurs="1"> <xs:choice minOccurs="0" maxOccurs="1">
<xs:element name="filePath" type="dc:regexStringType"/> <xs:element name="filePath" type="dc:regexStringType"/>
<xs:element name="sha1" type="dc:sha1Type"/> <xs:element name="sha1" type="dc:sha1Type"/>
<xs:element name="gav" type="dc:regexStringType"/>
</xs:choice> </xs:choice>
<xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="cpe" type="dc:regexStringType"/> <xs:element name="cpe" type="dc:regexStringType"/>

View File

@@ -339,7 +339,7 @@ public class SuppressionRuleTest {
} }
/** /**
* Test of cpeMatches method, of class SuppressionRule. * Test of identifierMatches method, of class SuppressionRule.
*/ */
@Test @Test
public void testCpeMatches() { public void testCpeMatches() {
@@ -350,44 +350,44 @@ public class SuppressionRuleTest {
SuppressionRule instance = new SuppressionRule(); SuppressionRule instance = new SuppressionRule();
boolean expResult = true; boolean expResult = true;
boolean result = instance.cpeMatches(cpe, identifier); boolean result = instance.identifierMatches(cpe, identifier);
assertEquals(expResult, result); assertEquals(expResult, result);
cpe.setValue("cpe:/a:microsoft:.net_framework:4.0"); cpe.setValue("cpe:/a:microsoft:.net_framework:4.0");
expResult = false; expResult = false;
result = instance.cpeMatches(cpe, identifier); result = instance.identifierMatches(cpe, identifier);
assertEquals(expResult, result); assertEquals(expResult, result);
cpe.setValue("CPE:/a:microsoft:.net_framework:4.5"); cpe.setValue("CPE:/a:microsoft:.net_framework:4.5");
cpe.setCaseSensitive(true); cpe.setCaseSensitive(true);
expResult = false; expResult = false;
result = instance.cpeMatches(cpe, identifier); result = instance.identifierMatches(cpe, identifier);
assertEquals(expResult, result); assertEquals(expResult, result);
cpe.setValue("cpe:/a:microsoft:.net_framework"); cpe.setValue("cpe:/a:microsoft:.net_framework");
cpe.setCaseSensitive(false); cpe.setCaseSensitive(false);
expResult = true; expResult = true;
result = instance.cpeMatches(cpe, identifier); result = instance.identifierMatches(cpe, identifier);
assertEquals(expResult, result); assertEquals(expResult, result);
cpe.setValue("cpe:/a:microsoft:.*"); cpe.setValue("cpe:/a:microsoft:.*");
cpe.setRegex(true); cpe.setRegex(true);
expResult = true; expResult = true;
result = instance.cpeMatches(cpe, identifier); result = instance.identifierMatches(cpe, identifier);
assertEquals(expResult, result); assertEquals(expResult, result);
cpe.setValue("CPE:/a:microsoft:.*"); cpe.setValue("CPE:/a:microsoft:.*");
cpe.setRegex(true); cpe.setRegex(true);
cpe.setCaseSensitive(true); cpe.setCaseSensitive(true);
expResult = false; expResult = false;
result = instance.cpeMatches(cpe, identifier); result = instance.identifierMatches(cpe, identifier);
assertEquals(expResult, result); assertEquals(expResult, result);
cpe.setValue("cpe:/a:apache:.*"); cpe.setValue("cpe:/a:apache:.*");
cpe.setRegex(true); cpe.setRegex(true);
cpe.setCaseSensitive(false); cpe.setCaseSensitive(false);
expResult = false; expResult = false;
result = instance.cpeMatches(cpe, identifier); result = instance.identifierMatches(cpe, identifier);
assertEquals(expResult, result); assertEquals(expResult, result);
} }
@@ -398,7 +398,7 @@ public class SuppressionRuleTest {
public void testProcess() { public void testProcess() {
File struts = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); File struts = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath());
Dependency dependency = new Dependency(struts); 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(); String sha1 = dependency.getSha1sum();
dependency.setSha1sum("384FAA82E193D4E4B0546059CA09572654BC3970"); dependency.setSha1sum("384FAA82E193D4E4B0546059CA09572654BC3970");
Vulnerability v = createVulnerability(); Vulnerability v = createVulnerability();
@@ -455,9 +455,9 @@ public class SuppressionRuleTest {
assertTrue(dependency.getIdentifiers().isEmpty()); assertTrue(dependency.getIdentifiers().isEmpty());
assertTrue(dependency.getSuppressedIdentifiers().size() == 1); assertTrue(dependency.getSuppressedIdentifiers().size() == 1);
dependency.addIdentifier("cwe", "cpe:/a:microsoft:.net_framework:4.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("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");
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:5.0", "some url not needed for this test");
pt = new PropertyType(); pt = new PropertyType();
pt.setValue("cpe:/a:microsoft:.net_framework"); pt.setValue("cpe:/a:microsoft:.net_framework");
instance.addCpe(pt); instance.addCpe(pt);