Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Hans Aikema
2017-02-21 17:35:30 +01:00
9 changed files with 154 additions and 64 deletions

View File

@@ -166,9 +166,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
*/ */
private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
//</editor-fold> //</editor-fold>
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer"> //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
/** /**
* Returns the FileFilter. * Returns the FileFilter.
@@ -541,6 +539,12 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
addMatchingValues(classes, org, dependency.getVendorEvidence()); addMatchingValues(classes, org, dependency.getVendorEvidence());
addMatchingValues(classes, org, dependency.getProductEvidence()); 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 //pom name
final String pomName = pom.getName(); final String pomName = pom.getName();
if (pomName if (pomName
@@ -1110,6 +1114,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
* Stores information about a class name. * Stores information about a class name.
*/ */
protected static class ClassNameInformation { protected static class ClassNameInformation {
/** /**
* The fully qualified class name. * The fully qualified class name.
*/ */
@@ -1180,6 +1185,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
/** /**
* Get the value of packageStructure * Get the value of packageStructure
* *

View File

@@ -18,10 +18,11 @@
package org.owasp.dependencycheck.dependency; package org.owasp.dependencycheck.dependency;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.commons.lang3.builder.CompareToBuilder; import org.apache.commons.lang3.builder.CompareToBuilder;
/** /**
@@ -139,6 +140,21 @@ public class Vulnerability implements Serializable, Comparable<Vulnerability> {
return references; 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<Reference> getReferences(boolean sorted) {
List<Reference> sortedRefs = new ArrayList<>(this.references);
if (sorted) {
Collections.sort(sortedRefs);
}
return sortedRefs;
}
/** /**
* Set the value of references. * Set the value of references.
* *
@@ -181,6 +197,21 @@ public class Vulnerability implements Serializable, Comparable<Vulnerability> {
return vulnerableSoftware; 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<VulnerableSoftware> getVulnerableSoftware(boolean sorted) {
List<VulnerableSoftware> sortedVulnerableSoftware = new ArrayList<>(this.vulnerableSoftware);
if (sorted) {
Collections.sort(sortedVulnerableSoftware);
}
return sortedVulnerableSoftware;
}
/** /**
* Set the value of vulnerableSoftware. * Set the value of vulnerableSoftware.
* *
@@ -398,15 +429,14 @@ public class Vulnerability implements Serializable, Comparable<Vulnerability> {
final StringBuilder sb = new StringBuilder("Vulnerability "); final StringBuilder sb = new StringBuilder("Vulnerability ");
sb.append(this.name); sb.append(this.name);
sb.append("\nReferences:\n"); sb.append("\nReferences:\n");
SortedSet<Reference> sortedReferences = new TreeSet<Reference>(this.references); for (Reference reference : getReferences(true)) {
for (Reference reference : sortedReferences) {
sb.append("=> "); sb.append("=> ");
sb.append(reference); sb.append(reference);
sb.append("\n"); sb.append("\n");
} }
sb.append("\nSoftware:\n"); sb.append("\nSoftware:\n");
SortedSet<VulnerableSoftware> sortedVulnerableSoftware = new TreeSet<VulnerableSoftware>(this.vulnerableSoftware);
for (VulnerableSoftware software : sortedVulnerableSoftware) { for (VulnerableSoftware software : getVulnerableSoftware(true)) {
sb.append("=> "); sb.append("=> ");
sb.append(software); sb.append(software);
sb.append("\n"); sb.append("\n");

View File

@@ -39,6 +39,10 @@ public class Model {
* The organization name. * The organization name.
*/ */
private String organization; private String organization;
/**
* The organization URL.
*/
private String organizationUrl;
/** /**
* The description. * The description.
*/ */
@@ -112,6 +116,24 @@ public class Model {
this.organization = organization; 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. * Get the value of description.
* *

View File

@@ -132,48 +132,66 @@ public class PomHandler extends DefaultHandler {
public void endElement(String uri, String localName, String qName) throws SAXException { public void endElement(String uri, String localName, String qName) throws SAXException {
stack.pop(); stack.pop();
final String parentNode = stack.peek(); final String parentNode = stack.peek();
if (PROJECT.equals(parentNode)) { if (null != parentNode) switch (parentNode) {
if (GROUPID.equals(qName)) { case PROJECT:
model.setGroupId(currentText.toString()); if (null != qName) switch (qName) {
} else if (ARTIFACTID.equals(qName)) { case GROUPID:
model.setArtifactId(currentText.toString()); model.setGroupId(currentText.toString());
} else if (VERSION.equals(qName)) { break;
model.setVersion(currentText.toString()); case ARTIFACTID:
} else if (NAME.equals(qName)) { model.setArtifactId(currentText.toString());
model.setName(currentText.toString()); break;
} else if (ORGANIZATION.equals(qName)) { case VERSION:
model.setOrganization(currentText.toString()); model.setVersion(currentText.toString());
} else if (DESCRIPTION.equals(qName)) { break;
model.setDescription(currentText.toString()); case NAME:
} else if (URL.equals(qName)) { model.setName(currentText.toString());
model.setProjectURL(currentText.toString()); break;
} case DESCRIPTION:
} else if (PARENT.equals(parentNode)) { model.setDescription(currentText.toString());
if (GROUPID.equals(qName)) { break;
model.setParentGroupId(currentText.toString()); case URL:
} else if (ARTIFACTID.equals(qName)) { model.setProjectURL(currentText.toString());
model.setParentArtifactId(currentText.toString()); break;
} else if (VERSION.equals(qName)) { default:
model.setParentVersion(currentText.toString()); break;
} } break;
} else if (LICENSE.equals(parentNode)) { case ORGANIZATION:
if (license != null) {
if (NAME.equals(qName)) { if (NAME.equals(qName)) {
license.setName(currentText.toString()); model.setOrganization(currentText.toString());
} else if (URL.equals(qName)) { } else if (URL.equals(qName)) {
license.setUrl(currentText.toString()); model.setOrganizationUrl(currentText.toString());
} } break;
//} else { case PARENT:
//TODO add error logging if (null != qName) switch (qName) {
} case GROUPID:
} else if (LICENSES.equals(parentNode)) { model.setParentGroupId(currentText.toString());
if (LICENSE.equals(qName)) { break;
case ARTIFACTID:
model.setParentArtifactId(currentText.toString());
break;
case VERSION:
model.setParentVersion(currentText.toString());
break;
default:
break;
} break;
case LICENSE:
if (license != null) { if (license != null) {
model.addLicense(license); if (NAME.equals(qName)) {
//} else { license.setName(currentText.toString());
//TODO add error logging } 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;
} }
} }

View File

@@ -47,7 +47,7 @@ public final class PomUtils {
* Reads in the specified POM and converts it to a Model. * Reads in the specified POM and converts it to a Model.
* *
* @param file the pom.xml file * @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 * @throws AnalysisException is thrown if there is an exception extracting
* or parsing the POM {@link Model} object * 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())); throw new AnalysisException(String.format("Unable to parse pom '%s'", file.getPath()));
} }
return model; return model;
} catch (AnalysisException ex) {
throw ex;
} catch (PomParseException ex) { } catch (PomParseException ex) {
LOGGER.warn("Unable to parse pom '{}'", file.getPath()); LOGGER.warn("Unable to parse pom '{}'", file.getPath());
LOGGER.debug("", ex); LOGGER.debug("", ex);
throw new AnalysisException(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) { } catch (Throwable ex) {
LOGGER.warn("Unexpected error during parsing of the pom '{}'", file.getPath()); LOGGER.warn("Unexpected error during parsing of the pom '{}'", file.getPath());
LOGGER.debug("", ex); 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 path the path to the pom.xml file within the jar file
* @param jar the jar file to extract the pom from * @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 * @throws AnalysisException is thrown if there is an exception extracting
* or parsing the POM {@link Model} object * or parsing the POM {@link Model} object
*/ */
@@ -93,6 +91,8 @@ public final class PomUtils {
if (model == null) { if (model == null) {
throw new AnalysisException(String.format("Unable to parse pom '%s/%s'", jar.getName(), path)); throw new AnalysisException(String.format("Unable to parse pom '%s/%s'", jar.getName(), path));
} }
} catch (AnalysisException ex) {
throw ex;
} catch (SecurityException ex) { } catch (SecurityException ex) {
LOGGER.warn("Unable to parse pom '{}' in jar '{}'; invalid signature", path, jar.getName()); LOGGER.warn("Unable to parse pom '{}' in jar '{}'; invalid signature", path, jar.getName());
LOGGER.debug("", ex); LOGGER.debug("", ex);

View File

@@ -842,7 +842,7 @@ Getting Help: <a href="https://groups.google.com/forum/#!forum/dependency-check"
<p>$enc.html($vuln.description) <p>$enc.html($vuln.description)
#if ($vuln.getReferences().size()>0) #if ($vuln.getReferences().size()>0)
<ul> <ul>
#foreach($ref in $vuln.getReferences()) #foreach($ref in $vuln.getReferences(true))
<li>$enc.html($ref.source) - <a target="_blank" href="$enc.html($ref.url)">$ref.name</a></li> <li>$enc.html($ref.source) - <a target="_blank" href="$enc.html($ref.url)">$ref.name</a></li>
#end #end
</ul> </ul>
@@ -857,7 +857,7 @@ Getting Help: <a href="https://groups.google.com/forum/#!forum/dependency-check"
<p>Vulnerable Software &amp; Versions:&nbsp;(<a href="#" onclick="return toggleDisplay(this,'.vs$vsctr', 'show all', 'show less');">show all</a>)<ul> <p>Vulnerable Software &amp; Versions:&nbsp;(<a href="#" onclick="return toggleDisplay(this,'.vs$vsctr', 'show all', 'show less');">show all</a>)<ul>
<li class="vs$vsctr"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vuln.matchedCPE)">$enc.html($vuln.matchedCPE)</a> #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end</li> <li class="vs$vsctr"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vuln.matchedCPE)">$enc.html($vuln.matchedCPE)</a> #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end</li>
<li class="vs$vsctr">...</li> <li class="vs$vsctr">...</li>
#foreach($vs in $vuln.getVulnerableSoftware()) #foreach($vs in $vuln.getVulnerableSoftware(true))
<li class="vs$vsctr hidden"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vs.name)">$enc.html($vs.name)</a> #if($vs.hasPreviousVersion()) and all previous versions#end</li> <li class="vs$vsctr hidden"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vs.name)">$enc.html($vs.name)</a> #if($vs.hasPreviousVersion()) and all previous versions#end</li>
#end #end
</ul></p> </ul></p>
@@ -977,7 +977,7 @@ Getting Help: <a href="https://groups.google.com/forum/#!forum/dependency-check"
<p>$enc.html($vuln.description) <p>$enc.html($vuln.description)
#if ($vuln.getReferences().size()>0) #if ($vuln.getReferences().size()>0)
<ul> <ul>
#foreach($ref in $vuln.getReferences()) #foreach($ref in $vuln.getReferences(true))
<li>$enc.html($ref.source) - <a target="_blank" href="$enc.html($ref.url)">$ref.name</a></li> <li>$enc.html($ref.source) - <a target="_blank" href="$enc.html($ref.url)">$ref.name</a></li>
#end #end
</ul> </ul>
@@ -991,7 +991,7 @@ Getting Help: <a href="https://groups.google.com/forum/#!forum/dependency-check"
<p>Vulnerable Software &amp; Versions:&nbsp;(<a href="#" onclick="return toggleDisplay(this,'.vs$vsctr', 'show all', 'show less');">show all</a>)<ul> <p>Vulnerable Software &amp; Versions:&nbsp;(<a href="#" onclick="return toggleDisplay(this,'.vs$vsctr', 'show all', 'show less');">show all</a>)<ul>
<li class="vs$vsctr"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vuln.matchedCPE)">$enc.html($vuln.matchedCPE)</a> #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end</li> <li class="vs$vsctr"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vuln.matchedCPE)">$enc.html($vuln.matchedCPE)</a> #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end</li>
<li class="vs$vsctr">...</li> <li class="vs$vsctr">...</li>
#foreach($vs in $vuln.getVulnerableSoftware()) #foreach($vs in $vuln.getVulnerableSoftware(true))
<li class="vs$vsctr hidden"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vs.name)">$enc.html($vs.name)</a> #if($vs.hasPreviousVersion()) and all previous versions#end</li> <li class="vs$vsctr hidden"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vs.name)">$enc.html($vs.name)</a> #if($vs.hasPreviousVersion()) and all previous versions#end</li>
#end #end
</ul></p> </ul></p>

View File

@@ -141,7 +141,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
#end #end
<description>$enc.xml($vuln.description)</description> <description>$enc.xml($vuln.description)</description>
<references> <references>
#foreach($ref in $vuln.getReferences()) #foreach($ref in $vuln.getReferences(true))
<reference> <reference>
<source>$enc.xml($ref.source)</source> <source>$enc.xml($ref.source)</source>
<url>$enc.xml($ref.url)</url> <url>$enc.xml($ref.url)</url>
@@ -150,7 +150,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
#end #end
</references> </references>
<vulnerableSoftware> <vulnerableSoftware>
#foreach($vs in $vuln.getVulnerableSoftware()) #foreach($vs in $vuln.getVulnerableSoftware(true))
<software#if($vs.hasPreviousVersion()) allPreviousVersion="true"#end>$enc.xml($vs.name)</software> <software#if($vs.hasPreviousVersion()) allPreviousVersion="true"#end>$enc.xml($vs.name)</software>
#end #end
</vulnerableSoftware> </vulnerableSoftware>
@@ -172,7 +172,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
#end #end
<description>$enc.xml($vuln.description)</description> <description>$enc.xml($vuln.description)</description>
<references> <references>
#foreach($ref in $vuln.getReferences()) #foreach($ref in $vuln.getReferences(true))
<reference> <reference>
<source>$enc.xml($ref.source)</source> <source>$enc.xml($ref.source)</source>
<url>$enc.xml($ref.url)</url> <url>$enc.xml($ref.url)</url>
@@ -181,7 +181,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
#end #end
</references> </references>
<vulnerableSoftware> <vulnerableSoftware>
#foreach($vs in $vuln.getVulnerableSoftware()) #foreach($vs in $vuln.getVulnerableSoftware(true))
<software#if($vs.hasPreviousVersion()) allPreviousVersion="true"#end>$enc.xml($vs.name)</software> <software#if($vs.hasPreviousVersion()) allPreviousVersion="true"#end>$enc.xml($vs.name)</software>
#end #end
</vulnerableSoftware> </vulnerableSoftware>

View File

@@ -24,13 +24,17 @@ import static org.junit.Assert.*;
import org.owasp.dependencycheck.BaseTest; import org.owasp.dependencycheck.BaseTest;
/** /**
* Test the PomUtils object.
* *
* @author jeremy * @author Jeremy Long
*/ */
public class PomUtilsTest extends BaseTest { public class PomUtilsTest extends BaseTest {
/** /**
* Test of readPom method, of class PomUtils. * Test of readPom method, of class PomUtils.
*
* @throws java.lang.Exception thrown when the test fails due to an
* exception
*/ */
@Test @Test
public void testReadPom_File() throws Exception { public void testReadPom_File() throws Exception {
@@ -39,6 +43,11 @@ public class PomUtilsTest extends BaseTest {
Model result = PomUtils.readPom(file); Model result = PomUtils.readPom(file);
assertEquals(expResult, result.getName()); 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"); file = BaseTest.getResourceAsFile(this, "jmockit-1.26.pom");
expResult = "Main"; expResult = "Main";
result = PomUtils.readPom(file); result = PomUtils.readPom(file);

View File

@@ -25,6 +25,11 @@
<archive>https://dwr.dev.java.net/servlets/SummarizeList?listName=announce</archive> <archive>https://dwr.dev.java.net/servlets/SummarizeList?listName=announce</archive>
</mailingList> </mailingList>
</mailingLists> </mailingLists>
<!-- added the organization for testing purposes-->
<organization>
<name>get ahead</name>
<url>http://getahead.ltd.uk/dwr</url>
</organization>
<developers> <developers>
<developer> <developer>
<id>joe_walker</id> <id>joe_walker</id>