From d31e0453bd497b9a6de8f10a8b9f7b1e92c52ea1 Mon Sep 17 00:00:00 2001
From: Jeremy Long
Date: Mon, 20 Feb 2017 07:01:05 -0500
Subject: [PATCH 1/4] fix for #660
---
.../main/resources/dependencycheck-base-suppression.xml | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml b/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml
index 409bf11e6..ddc239276 100644
--- a/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml
+++ b/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml
@@ -507,4 +507,12 @@
^io\.jsonwebtoken:jjwt:.*$
cpe:/a:sonatype:nexus
+
+
+ ^commons-validator:commons-validator:.*$
+ cpe:/a:apache:http_server
+ cpe:/a:apache:apache_http_server
+
From a5990ea6f39b0c4d5dec9ccfb06815ebc145285c Mon Sep 17 00:00:00 2001
From: Jeremy Long
Date: Tue, 21 Feb 2017 06:38:31 -0500
Subject: [PATCH 2/4] update to #657 to allow sorted vulnerable software in
repots; also, sorting an array list is faster then building a treeset
---
.../dependency/Vulnerability.java | 42 ++++++++++++++++---
.../main/resources/templates/HtmlReport.vsl | 8 ++--
.../main/resources/templates/XmlReport.vsl | 8 ++--
3 files changed, 44 insertions(+), 14 deletions(-)
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 aac408a02..1720edda8 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
@@ -18,10 +18,11 @@
package org.owasp.dependencycheck.dependency;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
import org.apache.commons.lang3.builder.CompareToBuilder;
/**
@@ -139,6 +140,21 @@ public class Vulnerability implements Serializable, Comparable {
return references;
}
+ /**
+ * Returns the list of references. This is primarily used within the
+ * generated reports.
+ *
+ * @param sorted whether the returned list should be sorted
+ * @return the list of references
+ */
+ public List getReferences(boolean sorted) {
+ List sortedRefs = new ArrayList<>(this.references);
+ if (sorted) {
+ Collections.sort(sortedRefs);
+ }
+ return sortedRefs;
+ }
+
/**
* Set the value of references.
*
@@ -181,6 +197,21 @@ public class Vulnerability implements Serializable, Comparable {
return vulnerableSoftware;
}
+ /**
+ * Returns a sorted list of vulnerable software. This is primarily used for
+ * display within reports.
+ *
+ * @param sorted whether or not the list should be sorted
+ * @return the list of vulnerable software
+ */
+ public List getVulnerableSoftware(boolean sorted) {
+ List sortedVulnerableSoftware = new ArrayList<>(this.vulnerableSoftware);
+ if (sorted) {
+ Collections.sort(sortedVulnerableSoftware);
+ }
+ return sortedVulnerableSoftware;
+ }
+
/**
* Set the value of vulnerableSoftware.
*
@@ -398,15 +429,14 @@ public class Vulnerability implements Serializable, Comparable {
final StringBuilder sb = new StringBuilder("Vulnerability ");
sb.append(this.name);
sb.append("\nReferences:\n");
- SortedSet sortedReferences = new TreeSet(this.references);
- for (Reference reference : sortedReferences) {
+ for (Reference reference : getReferences(true)) {
sb.append("=> ");
sb.append(reference);
sb.append("\n");
}
sb.append("\nSoftware:\n");
- SortedSet sortedVulnerableSoftware = new TreeSet(this.vulnerableSoftware);
- for (VulnerableSoftware software : sortedVulnerableSoftware) {
+
+ for (VulnerableSoftware software : getVulnerableSoftware(true)) {
sb.append("=> ");
sb.append(software);
sb.append("\n");
diff --git a/dependency-check-core/src/main/resources/templates/HtmlReport.vsl b/dependency-check-core/src/main/resources/templates/HtmlReport.vsl
index 7da1e3c15..02035e96e 100644
--- a/dependency-check-core/src/main/resources/templates/HtmlReport.vsl
+++ b/dependency-check-core/src/main/resources/templates/HtmlReport.vsl
@@ -842,7 +842,7 @@ Getting Help: $enc.html($vuln.description)
#if ($vuln.getReferences().size()>0)
- #foreach($ref in $vuln.getReferences())
+ #foreach($ref in $vuln.getReferences(true))
$enc.html($ref.source) - $ref.name
#end
@@ -857,7 +857,7 @@ Getting Help: Vulnerable Software & Versions: ( show all )
$enc.html($vuln.matchedCPE) #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end
...
- #foreach($vs in $vuln.getVulnerableSoftware())
+ #foreach($vs in $vuln.getVulnerableSoftware(true))
$enc.html($vs.name) #if($vs.hasPreviousVersion()) and all previous versions#end
#end
@@ -977,7 +977,7 @@ Getting Help: $enc.html($vuln.description)
#if ($vuln.getReferences().size()>0)
- #foreach($ref in $vuln.getReferences())
+ #foreach($ref in $vuln.getReferences(true))
$enc.html($ref.source) - $ref.name
#end
@@ -991,7 +991,7 @@ Getting Help: Vulnerable Software & Versions: ( show all )
$enc.html($vuln.matchedCPE) #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end
...
- #foreach($vs in $vuln.getVulnerableSoftware())
+ #foreach($vs in $vuln.getVulnerableSoftware(true))
$enc.html($vs.name) #if($vs.hasPreviousVersion()) and all previous versions#end
#end
diff --git a/dependency-check-core/src/main/resources/templates/XmlReport.vsl b/dependency-check-core/src/main/resources/templates/XmlReport.vsl
index 8e71e1dc7..0bfd8c49c 100644
--- a/dependency-check-core/src/main/resources/templates/XmlReport.vsl
+++ b/dependency-check-core/src/main/resources/templates/XmlReport.vsl
@@ -141,7 +141,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
#end
$enc.xml($vuln.description)
-#foreach($ref in $vuln.getReferences())
+#foreach($ref in $vuln.getReferences(true))
$enc.xml($ref.source)
$enc.xml($ref.url)
@@ -150,7 +150,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
#end
-#foreach($vs in $vuln.getVulnerableSoftware())
+#foreach($vs in $vuln.getVulnerableSoftware(true))
$enc.xml($vs.name)
#end
@@ -172,7 +172,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
#end
$enc.xml($vuln.description)
-#foreach($ref in $vuln.getReferences())
+#foreach($ref in $vuln.getReferences(true))
$enc.xml($ref.source)
$enc.xml($ref.url)
@@ -181,7 +181,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
#end
-#foreach($vs in $vuln.getVulnerableSoftware())
+#foreach($vs in $vuln.getVulnerableSoftware(true))
$enc.xml($vs.name)
#end
From 2ea0eb3c640c866f771f655de0097449f7935abf Mon Sep 17 00:00:00 2001
From: Jeremy Long
Date: Tue, 21 Feb 2017 06:40:02 -0500
Subject: [PATCH 3/4] correct fix for issue #660; correctly handle organization
from the pom
---
.../dependencycheck/analyzer/JarAnalyzer.java | 10 +-
.../owasp/dependencycheck/xml/pom/Model.java | 22 +++++
.../dependencycheck/xml/pom/PomHandler.java | 98 +++++++++++--------
.../dependencycheck/xml/pom/PomUtils.java | 12 +--
.../dependencycheck-base-suppression.xml | 8 --
.../dependencycheck/xml/pom/PomUtilsTest.java | 13 ++-
6 files changed, 105 insertions(+), 58 deletions(-)
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java
index 8cba0c48c..dca3b7b6e 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java
@@ -166,9 +166,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
*/
private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
-
//
-
//
/**
* Returns the FileFilter.
@@ -541,6 +539,12 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
addMatchingValues(classes, org, dependency.getVendorEvidence());
addMatchingValues(classes, org, dependency.getProductEvidence());
}
+ // org name
+ final String orgUrl = pom.getOrganizationUrl();
+ if (orgUrl != null && !orgUrl.isEmpty()) {
+ dependency.getVendorEvidence().addEvidence("pom", "organization url", orgUrl, Confidence.MEDIUM);
+ dependency.getProductEvidence().addEvidence("pom", "organization url", orgUrl, Confidence.LOW);
+ }
//pom name
final String pomName = pom.getName();
if (pomName
@@ -1110,6 +1114,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
* Stores information about a class name.
*/
protected static class ClassNameInformation {
+
/**
* The fully qualified class name.
*/
@@ -1180,6 +1185,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
public void setName(String name) {
this.name = name;
}
+
/**
* Get the value of packageStructure
*
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/Model.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/Model.java
index 0d6ac691e..132f10daf 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/Model.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/Model.java
@@ -39,6 +39,10 @@ public class Model {
* The organization name.
*/
private String organization;
+ /**
+ * The organization URL.
+ */
+ private String organizationUrl;
/**
* The description.
*/
@@ -112,6 +116,24 @@ public class Model {
this.organization = organization;
}
+ /**
+ * Get the value of organizationUrl.
+ *
+ * @return the value of organizationUrl
+ */
+ public String getOrganizationUrl() {
+ return organizationUrl;
+ }
+
+ /**
+ * Set the value of organizationUrl.
+ *
+ * @param organizationUrl new value of organizationUrl
+ */
+ public void setOrganizationUrl(String organizationUrl) {
+ this.organizationUrl = organizationUrl;
+ }
+
/**
* Get the value of description.
*
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/PomHandler.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/PomHandler.java
index 669ab9d0d..198ce2e12 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/PomHandler.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/PomHandler.java
@@ -101,7 +101,7 @@ public class PomHandler extends DefaultHandler {
* The current node text being extracted from the element.
*/
private StringBuilder currentText;
-
+
/**
* Handles the start element event.
*
@@ -132,48 +132,66 @@ public class PomHandler extends DefaultHandler {
public void endElement(String uri, String localName, String qName) throws SAXException {
stack.pop();
final String parentNode = stack.peek();
- if (PROJECT.equals(parentNode)) {
- if (GROUPID.equals(qName)) {
- model.setGroupId(currentText.toString());
- } else if (ARTIFACTID.equals(qName)) {
- model.setArtifactId(currentText.toString());
- } else if (VERSION.equals(qName)) {
- model.setVersion(currentText.toString());
- } else if (NAME.equals(qName)) {
- model.setName(currentText.toString());
- } else if (ORGANIZATION.equals(qName)) {
- model.setOrganization(currentText.toString());
- } else if (DESCRIPTION.equals(qName)) {
- model.setDescription(currentText.toString());
- } else if (URL.equals(qName)) {
- model.setProjectURL(currentText.toString());
- }
- } else if (PARENT.equals(parentNode)) {
- if (GROUPID.equals(qName)) {
- model.setParentGroupId(currentText.toString());
- } else if (ARTIFACTID.equals(qName)) {
- model.setParentArtifactId(currentText.toString());
- } else if (VERSION.equals(qName)) {
- model.setParentVersion(currentText.toString());
- }
- } else if (LICENSE.equals(parentNode)) {
- if (license != null) {
+ if (null != parentNode) switch (parentNode) {
+ case PROJECT:
+ if (null != qName) switch (qName) {
+ case GROUPID:
+ model.setGroupId(currentText.toString());
+ break;
+ case ARTIFACTID:
+ model.setArtifactId(currentText.toString());
+ break;
+ case VERSION:
+ model.setVersion(currentText.toString());
+ break;
+ case NAME:
+ model.setName(currentText.toString());
+ break;
+ case DESCRIPTION:
+ model.setDescription(currentText.toString());
+ break;
+ case URL:
+ model.setProjectURL(currentText.toString());
+ break;
+ default:
+ break;
+ } break;
+ case ORGANIZATION:
if (NAME.equals(qName)) {
- license.setName(currentText.toString());
+ model.setOrganization(currentText.toString());
} else if (URL.equals(qName)) {
- license.setUrl(currentText.toString());
- }
- //} else {
- //TODO add error logging
- }
- } else if (LICENSES.equals(parentNode)) {
- if (LICENSE.equals(qName)) {
+ model.setOrganizationUrl(currentText.toString());
+ } break;
+ case PARENT:
+ if (null != qName) switch (qName) {
+ case GROUPID:
+ model.setParentGroupId(currentText.toString());
+ break;
+ case ARTIFACTID:
+ model.setParentArtifactId(currentText.toString());
+ break;
+ case VERSION:
+ model.setParentVersion(currentText.toString());
+ break;
+ default:
+ break;
+ } break;
+ case LICENSE:
if (license != null) {
- model.addLicense(license);
- //} else {
- //TODO add error logging
- }
- }
+ if (NAME.equals(qName)) {
+ license.setName(currentText.toString());
+ } else if (URL.equals(qName)) {
+ license.setUrl(currentText.toString());
+ }
+ } break;
+ case LICENSES:
+ if (LICENSE.equals(qName)) {
+ if (license != null) {
+ model.addLicense(license);
+ }
+ } break;
+ default:
+ break;
}
}
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/PomUtils.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/PomUtils.java
index 6f3aa4987..4a6d2e8fc 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/PomUtils.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/PomUtils.java
@@ -47,7 +47,7 @@ public final class PomUtils {
* Reads in the specified POM and converts it to a Model.
*
* @param file the pom.xml file
- * @return returns a
+ * @return returns an object representation of the POM
* @throws AnalysisException is thrown if there is an exception extracting
* or parsing the POM {@link Model} object
*/
@@ -59,14 +59,12 @@ public final class PomUtils {
throw new AnalysisException(String.format("Unable to parse pom '%s'", file.getPath()));
}
return model;
+ } catch (AnalysisException ex) {
+ throw ex;
} catch (PomParseException ex) {
LOGGER.warn("Unable to parse pom '{}'", file.getPath());
LOGGER.debug("", ex);
throw new AnalysisException(ex);
- } catch (IOException ex) {
- LOGGER.warn("Unable to parse pom '{}'(IO Exception)", file.getPath());
- LOGGER.debug("", ex);
- throw new AnalysisException(ex);
} catch (Throwable ex) {
LOGGER.warn("Unexpected error during parsing of the pom '{}'", file.getPath());
LOGGER.debug("", ex);
@@ -79,7 +77,7 @@ public final class PomUtils {
*
* @param path the path to the pom.xml file within the jar file
* @param jar the jar file to extract the pom from
- * @return returns a
+ * @return returns an object representation of the POM
* @throws AnalysisException is thrown if there is an exception extracting
* or parsing the POM {@link Model} object
*/
@@ -93,6 +91,8 @@ public final class PomUtils {
if (model == null) {
throw new AnalysisException(String.format("Unable to parse pom '%s/%s'", jar.getName(), path));
}
+ } catch (AnalysisException ex) {
+ throw ex;
} catch (SecurityException ex) {
LOGGER.warn("Unable to parse pom '{}' in jar '{}'; invalid signature", path, jar.getName());
LOGGER.debug("", ex);
diff --git a/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml b/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml
index ddc239276..409bf11e6 100644
--- a/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml
+++ b/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml
@@ -507,12 +507,4 @@
^io\.jsonwebtoken:jjwt:.*$
cpe:/a:sonatype:nexus
-
-
- ^commons-validator:commons-validator:.*$
- cpe:/a:apache:http_server
- cpe:/a:apache:apache_http_server
-
diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/pom/PomUtilsTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/pom/PomUtilsTest.java
index f16c05724..3b5c285bf 100644
--- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/pom/PomUtilsTest.java
+++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/pom/PomUtilsTest.java
@@ -24,13 +24,17 @@ import static org.junit.Assert.*;
import org.owasp.dependencycheck.BaseTest;
/**
+ * Test the PomUtils object.
*
- * @author jeremy
+ * @author Jeremy Long
*/
public class PomUtilsTest extends BaseTest {
/**
* Test of readPom method, of class PomUtils.
+ *
+ * @throws java.lang.Exception thrown when the test fails due to an
+ * exception
*/
@Test
public void testReadPom_File() throws Exception {
@@ -38,7 +42,12 @@ public class PomUtilsTest extends BaseTest {
String expResult = "Direct Web Remoting";
Model result = PomUtils.readPom(file);
assertEquals(expResult, result.getName());
-
+
+ expResult = "get ahead";
+ assertEquals(expResult, result.getOrganization());
+ expResult = "http://getahead.ltd.uk/dwr";
+ assertEquals(expResult, result.getOrganizationUrl());
+
file = BaseTest.getResourceAsFile(this, "jmockit-1.26.pom");
expResult = "Main";
result = PomUtils.readPom(file);
From 1367be510cddde1353af0b503340b1a03efcbf88 Mon Sep 17 00:00:00 2001
From: Jeremy Long
Date: Tue, 21 Feb 2017 07:02:05 -0500
Subject: [PATCH 4/4] correct fix for issue #660; correctly handle organization
from the pom
---
dependency-check-core/src/test/resources/dwr-pom.xml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/dependency-check-core/src/test/resources/dwr-pom.xml b/dependency-check-core/src/test/resources/dwr-pom.xml
index 1306c1a9c..0c43f0e84 100644
--- a/dependency-check-core/src/test/resources/dwr-pom.xml
+++ b/dependency-check-core/src/test/resources/dwr-pom.xml
@@ -25,6 +25,11 @@
https://dwr.dev.java.net/servlets/SummarizeList?listName=announce
+
+
+ get ahead
+ http://getahead.ltd.uk/dwr
+
joe_walker