diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Identifier.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Identifier.java index e376c03dd..a9ff9ca41 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Identifier.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Identifier.java @@ -20,21 +20,161 @@ package org.owasp.dependencycheck.dependency; import java.io.Serializable; /** + * In identifier such as a CPE or dependency coordinates (i.e. GAV). * * @author Jeremy Long */ public class Identifier implements Serializable, Comparable { + // /** * The serial version UID for serialization. */ private static final long serialVersionUID = 1L; + /** + * The confidence that this is the correct identifier. + */ + private Confidence confidence; + /** + * The value of the identifier + */ + private String value; + /** + * The url for the identifier. + */ + private String url; + /** + * The type of the identifier. + */ + private String type; + /** + * A description of the identifier. + */ + private String description; + /** + * Notes about the vulnerability. Generally used for suppression + * information. + */ + private String notes; + // + + // + /** + * Get the value of confidence. + * + * @return the value of confidence + */ + public Confidence getConfidence() { + return confidence; + } /** - * Default constructor. Should only be used for automatic class - * creation as is the case with many XML parsers (for the parsing - * of the Dependency-Check XML report). For all other use-cases, - * please use the non-default constructors. + * Set the value of confidence. + * + * @param confidence new value of confidence + */ + public void setConfidence(Confidence confidence) { + this.confidence = confidence; + } + + /** + * Get the value of value. + * + * @return the value of value + */ + public String getValue() { + return value; + } + + /** + * Set the value of value. + * + * @param value new value of value + */ + public void setValue(String value) { + this.value = value; + } + + /** + * Get the value of url. + * + * @return the value of url + */ + public String getUrl() { + return url; + } + + /** + * Set the value of url. + * + * @param url new value of url + */ + public void setUrl(String url) { + this.url = url; + } + + /** + * Get the value of type. + * + * @return the value of type + */ + public String getType() { + return type; + } + + /** + *

+ * Set the value of type.

+ * Example would be "CPE".

+ * + * @param type new value of type + */ + public void setType(String type) { + this.type = type; + } + + /** + * Get the value of description. + * + * @return the value of description + */ + public String getDescription() { + return description; + } + + /** + * Set the value of description. + * + * @param description new value of description + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * Get the value of notes from suppression notes. + * + * @return the value of notes + */ + public String getNotes() { + return notes; + } + + /** + * Set the value of notes. + * + * @param notes new value of notes + */ + public void setNotes(String notes) { + this.notes = notes; + } + //
+ + /** + * Default constructor. Should only be used for automatic class creation as + * is the case with many XML parsers (for the parsing of the + * Dependency-Check XML report). For all other use-cases, please use the + * non-default constructors. */ public Identifier() { } @@ -65,120 +205,6 @@ public class Identifier implements Serializable, Comparable { this.description = description; } - /** - * The confidence that this is the correct identifier. - */ - private Confidence confidence; - - /** - * Get the value of confidence. - * - * @return the value of confidence - */ - public Confidence getConfidence() { - return confidence; - } - - /** - * Set the value of confidence. - * - * @param confidence new value of confidence - */ - public void setConfidence(Confidence confidence) { - this.confidence = confidence; - } - - /** - * The value of the identifier - */ - private String value; - - /** - * Get the value of value. - * - * @return the value of value - */ - public String getValue() { - return value; - } - - /** - * Set the value of value. - * - * @param value new value of value - */ - public void setValue(String value) { - this.value = value; - } - /** - * The url for the identifier. - */ - private String url; - - /** - * Get the value of url. - * - * @return the value of url - */ - public String getUrl() { - return url; - } - - /** - * Set the value of url. - * - * @param url new value of url - */ - public void setUrl(String url) { - this.url = url; - } - /** - * The type of the identifier. - */ - private String type; - - /** - * Get the value of type. - * - * @return the value of type - */ - public String getType() { - return type; - } - - /** - *

- * Set the value of type.

- * Example would be "CPE".

- * - * @param type new value of type - */ - public void setType(String type) { - this.type = type; - } - /** - * A description of the identifier. - */ - private String description; - - /** - * Get the value of description. - * - * @return the value of description - */ - public String getDescription() { - return description; - } - - /** - * Set the value of description. - * - * @param description new value of description - */ - public void setDescription(String description) { - this.description = description; - } - @Override public boolean equals(Object obj) { if (obj == null) { @@ -213,7 +239,8 @@ public class Identifier implements Serializable, Comparable { } /** - * Implementation of the comparator interface. This compares the value of the identifier only. + * Implementation of the comparator interface. This compares the value of + * the identifier only. * * @param o the object being compared * @return an integer indicating the ordering diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Vulnerability.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Vulnerability.java index 1720edda8..013c8db79 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Vulnerability.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/dependency/Vulnerability.java @@ -94,6 +94,11 @@ public class Vulnerability implements Serializable, Comparable { * Whether or not all previous versions were affected. */ private String matchedAllPreviousCPE; + /** + * Notes about the vulnerability. Generally used for suppression + * information. + */ + private String notes; /** * Get the value of name. @@ -405,6 +410,24 @@ public class Vulnerability implements Serializable, Comparable { this.cvssAvailabilityImpact = cvssAvailabilityImpact; } + /** + * Get the value of notes from suppression notes. + * + * @return the value of notes + */ + public String getNotes() { + return notes; + } + + /** + * Set the value of notes. + * + * @param notes new value of cwe + */ + public void setNotes(String notes) { + this.notes = notes; + } + @Override public boolean equals(Object obj) { if (obj == null) { @@ -456,7 +479,6 @@ public class Vulnerability implements Serializable, Comparable { return new CompareToBuilder() .append(this.name, v.name) .toComparison(); - //return v.getName().compareTo(this.getName()); } /** @@ -497,4 +519,4 @@ public class Vulnerability implements Serializable, Comparable { public boolean hasMatchedAllPreviousCPE() { return matchedAllPreviousCPE != null; } -} +} \ No newline at end of file diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/reporting/ReportGenerator.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/reporting/ReportGenerator.java index 4847a43bf..e56f4fc75 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/reporting/ReportGenerator.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/reporting/ReportGenerator.java @@ -332,4 +332,4 @@ public class ReportGenerator { } } } -} +} \ No newline at end of file diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.java index 6c7f5f314..62c11ffc3 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.java @@ -46,6 +46,12 @@ public class SuppressionHandler extends DefaultHandler { * The CVE element name. */ public static final String CVE = "cve"; + + /** + * The CVE element name. + */ + public static final String NOTES = "notes"; + /** * The CPE element name. */ @@ -65,7 +71,16 @@ public class SuppressionHandler extends DefaultHandler { /** * A list of suppression rules. */ - private final List suppressionRules = new ArrayList<>(); + private final List suppressionRules = new ArrayList(); + + /** + * Get the value of suppressionRules. + * + * @return the value of suppressionRules + */ + public List getSuppressionRules() { + return suppressionRules; + } /** * The current rule being read. */ @@ -79,15 +94,6 @@ public class SuppressionHandler extends DefaultHandler { */ private StringBuilder currentText; - /** - * Get the value of suppressionRules. - * - * @return the value of suppressionRules - */ - public List getSuppressionRules() { - return suppressionRules; - } - /** * Handles the start element event. * @@ -122,27 +128,40 @@ public class SuppressionHandler extends DefaultHandler { */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { - if (SUPPRESS.equals(qName)) { - suppressionRules.add(rule); - rule = null; - } else if (FILE_PATH.equals(qName)) { - final PropertyType pt = processPropertyType(); - rule.setFilePath(pt); - } else if (SHA1.equals(qName)) { - rule.setSha1(currentText.toString()); - } else if (GAV.equals(qName)) { - final PropertyType pt = processPropertyType(); - rule.setGav(pt); - } else if (CPE.equals(qName)) { - final PropertyType pt = processPropertyType(); - rule.addCpe(pt); - } else if (CWE.equals(qName)) { - rule.addCwe(currentText.toString()); - } else if (CVE.equals(qName)) { - rule.addCve(currentText.toString()); - } else if (CVSS_BELOW.equals(qName)) { - final float cvss = Float.parseFloat(currentText.toString()); - rule.addCvssBelow(cvss); + if (null != qName) { + switch (qName) { + case SUPPRESS: + suppressionRules.add(rule); + rule = null; + break; + case FILE_PATH: + rule.setFilePath(processPropertyType()); + break; + case SHA1: + rule.setSha1(currentText.toString()); + break; + case GAV: + rule.setGav(processPropertyType()); + break; + case CPE: + rule.addCpe(processPropertyType()); + break; + case CWE: + rule.addCwe(currentText.toString()); + break; + case CVE: + rule.addCve(currentText.toString()); + break; + case NOTES: + rule.addNotes(currentText.toString()); + break; + case CVSS_BELOW: + final float cvss = Float.parseFloat(currentText.toString()); + rule.addCvssBelow(cvss); + break; + default: + break; + } } } @@ -180,4 +199,4 @@ public class SuppressionHandler extends DefaultHandler { } return pt; } -} +} \ No newline at end of file diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRule.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRule.java index 312cfb02b..30313be71 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRule.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRule.java @@ -59,6 +59,11 @@ public class SuppressionRule { * A Maven GAV to suppression. */ private PropertyType gav = null; + /** + * The notes added in suppression file + */ + + private String notes; /** * A flag indicating whether or not the suppression rule is a core/base rule @@ -175,6 +180,42 @@ public class SuppressionRule { return !cvssBelow.isEmpty(); } + /** + * Get the value of notes. + * + * @return the value of notes + */ + public String getNotes() { + return notes; + } + + /** + * Set the value of notes. + * + * @param notes new value of cve + */ + public void setNotes(String notes) { + this.notes = notes; + } + + /** + * Adds the notes to the cve list. + * + * @param notes the cve to add + */ + public void addNotes(String notes) { + this.notes = notes; + } + + /** + * Returns whether this suppression rule has notes entries. + * + * @return whether this suppression rule has notes entries + */ + public boolean hasNotes() { + return !cve.isEmpty(); + } + /** * Get the value of CWE. * @@ -328,6 +369,9 @@ public class SuppressionRule { for (PropertyType c : this.cpe) { if (identifierMatches("cpe", c, i)) { if (!isBase()) { + if (this.notes != null) { + i.setNotes(this.notes); + } dependency.addSuppressedIdentifier(i); } itr.remove(); @@ -369,6 +413,9 @@ public class SuppressionRule { } if (remove) { if (!isBase()) { + if (this.notes != null) { + v.setNotes(this.notes); + } dependency.addSuppressedVulnerability(v); } itr.remove(); @@ -482,4 +529,4 @@ public class SuppressionRule { sb.append('}'); return sb.toString(); } -} +} \ No newline at end of file diff --git a/dependency-check-core/src/main/resources/schema/dependency-check.1.4.xsd b/dependency-check-core/src/main/resources/schema/dependency-check.1.4.xsd new file mode 100644 index 000000000..01178fa7e --- /dev/null +++ b/dependency-check-core/src/main/resources/schema/dependency-check.1.4.xsd @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dependency-check-core/src/main/resources/templates/HtmlReport.vsl b/dependency-check-core/src/main/resources/templates/HtmlReport.vsl index 02035e96e..8283a443a 100644 --- a/dependency-check-core/src/main/resources/templates/HtmlReport.vsl +++ b/dependency-check-core/src/main/resources/templates/HtmlReport.vsl @@ -812,8 +812,15 @@ Getting Help: suppress #end - #if ($id.description) -
$enc.html($id.description) + #if ($id.description || $id.notes) +
    + #if ($id.description) +
  • Description: $enc.html($id.description)
  • + #end + #if ($id.notes) +
  • Notes: $enc.xml($id.notes)
  • + #end +
#end #end @@ -838,15 +845,18 @@ Getting Help:
CVSS Score: $vuln.cvssScore (AV:$enc.html($vuln.cvssAccessVector.substring(0,1))/AC:$enc.html($vuln.cvssAccessComplexity.substring(0,1))/Au:$enc.html($vuln.cvssAuthentication.substring(0,1))/C:$enc.html($vuln.cvssConfidentialityImpact.substring(0,1))/I:$enc.html($vuln.cvssIntegrityImpact.substring(0,1))/A:$enc.html($vuln.cvssAvailabilityImpact.substring(0,1))) #if ($vuln.cwe)
CWE: $vuln.cwe + #end + #if ($vuln.notes) +
Notes: $enc.xml($vuln.notes) #end

$enc.html($vuln.description) - #if ($vuln.getReferences().size()>0) -

+ #if ($vuln.getReferences().size()>0) +
    + #foreach($ref in $vuln.getReferences(true)) +
  • $enc.html($ref.source) - $ref.name
  • #end +
+ #end

#if ($vuln.getVulnerableSoftware().size()<2) @@ -947,8 +957,15 @@ Getting Help: Confidence:$id.confidence #end - #if ($id.description) -
$enc.html($id.description) + #if ($id.description || $id.notes) +
    + #if ($id.description) +
  • Description: $enc.html($id.description)
  • + #end + #if ($id.notes) +
  • Notes: $enc.xml($id.notes)
  • + #end +
#end #end @@ -973,6 +990,9 @@ Getting Help:
CVSS Score: $vuln.cvssScore #if ($vuln.cwe)
CWE: $vuln.cwe + #end + #if ($vuln.notes) +
Notes: $enc.xml($vuln.notes) #end

$enc.html($vuln.description) #if ($vuln.getReferences().size()>0) @@ -985,7 +1005,7 @@ Getting Help: #if ($vuln.getVulnerableSoftware().size()<2)

Vulnerable Software & Versions:

#else

Vulnerable Software & Versions: (show all)

    diff --git a/dependency-check-core/src/main/resources/templates/XmlReport.vsl b/dependency-check-core/src/main/resources/templates/XmlReport.vsl index 0bfd8c49c..143826c57 100644 --- a/dependency-check-core/src/main/resources/templates/XmlReport.vsl +++ b/dependency-check-core/src/main/resources/templates/XmlReport.vsl @@ -19,7 +19,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. @version 1.2 *# - + $version #foreach($prop in $properties.getMetaData().entrySet()) @@ -60,6 +60,9 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. ($id.value) #if( $id.url ) $enc.xml($id.url) +#end +#if ($id.notes) + $enc.xml($id.notes) #end #end @@ -101,6 +104,9 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. #end #if( $id.description ) $enc.xml($id.description) +#end +#if ($id.notes) + $enc.xml($id.notes) #end #end @@ -112,6 +118,9 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. #end #if( $id.description ) $enc.xml($id.description) +#end +#if ($id.notes) + $enc.xml($id.notes) #end #end @@ -140,8 +149,11 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. $enc.xml($vuln.cwe) #end $enc.xml($vuln.description) +#if ($vuln.notes) + $enc.xml($vuln.notes) +#end -#foreach($ref in $vuln.getReferences(true)) +#foreach($ref in $vuln.getReferences()) $enc.xml($ref.source) $enc.xml($ref.url) @@ -150,7 +162,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. #end -#foreach($vs in $vuln.getVulnerableSoftware(true)) +#foreach($vs in $vuln.getVulnerableSoftware()) $enc.xml($vs.name) #end @@ -160,6 +172,12 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. $enc.xml($vuln.name) $vuln.cvssScore + $enc.xml($vuln.cvssAccessVector) + $enc.xml($vuln.cvssAccessComplexity) + $enc.xml($vuln.cvssAuthentication) + $enc.xml($vuln.cvssConfidentialityImpact) + $enc.xml($vuln.cvssIntegrityImpact) + $enc.xml($vuln.cvssAvailabilityImpact) #if ($vuln.cvssScore<4.0) Low #elseif ($vuln.cvssScore>=7.0) @@ -171,8 +189,11 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. $enc.xml($vuln.cwe) #end $enc.xml($vuln.description) +#if ($vuln.notes) + $enc.xml($vuln.notes) +#end -#foreach($ref in $vuln.getReferences(true)) +#foreach($ref in $vuln.getReferences()) $enc.xml($ref.source) $enc.xml($ref.url) @@ -181,7 +202,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. #end -#foreach($vs in $vuln.getVulnerableSoftware(true)) +#foreach($vs in $vuln.getVulnerableSoftware()) $enc.xml($vs.name) #end diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java index d99fc732b..93a88170f 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java @@ -123,6 +123,9 @@ public class ReportGeneratorIntegrationTest extends BaseDBTestCase { f.mkdir(); } String writeTo = "target/test-reports/Report.xml"; + File suppressionFile = BaseTest.getResourceAsFile(this, "incorrectSuppressions.xml"); + + Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile.getAbsolutePath()); //File struts = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); File struts = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); @@ -151,7 +154,7 @@ public class ReportGeneratorIntegrationTest extends BaseDBTestCase { engine.cleanup(); - InputStream xsdStream = ReportGenerator.class.getClassLoader().getResourceAsStream("schema/dependency-check.1.3.xsd"); + InputStream xsdStream = ReportGenerator.class.getClassLoader().getResourceAsStream("schema/dependency-check.1.4.xsd"); StreamSource xsdSource = new StreamSource(xsdStream); StreamSource xmlSource = new StreamSource(new File(writeTo)); SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); diff --git a/dependency-check-core/src/test/resources/incorrectSuppressions.xml b/dependency-check-core/src/test/resources/incorrectSuppressions.xml new file mode 100644 index 000000000..9265da5ab --- /dev/null +++ b/dependency-check-core/src/test/resources/incorrectSuppressions.xml @@ -0,0 +1,17 @@ + + + + + ^jetty:org\.mortbay\.jetty:.*$ + cpe:/a:mortbay_jetty:jetty + + + + ^org\.apache\.struts:struts2-core:.*$ + CVE-2008-6504 + + \ No newline at end of file