diff --git a/pom.xml b/pom.xml index 4e49a20b5..3392e5a61 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ along with DependencyCheck. If not, see . 4.0.0 org.codesecure - DependencyCheck + dependency-check 0.2.5.2 jar diff --git a/src/main/java/org/codesecure/dependencycheck/analyzer/FileNameAnalyzer.java b/src/main/java/org/codesecure/dependencycheck/analyzer/FileNameAnalyzer.java index d5ebf8f7b..9b85e7bb2 100644 --- a/src/main/java/org/codesecure/dependencycheck/analyzer/FileNameAnalyzer.java +++ b/src/main/java/org/codesecure/dependencycheck/analyzer/FileNameAnalyzer.java @@ -95,7 +95,7 @@ public class FileNameAnalyzer implements Analyzer { String fileName = dependency.getFileName(); int pos = fileName.lastIndexOf("."); if (pos > 0) { - fileName = fileName.substring(0, pos - 1); + fileName = fileName.substring(0, pos); } dependency.getProductEvidence().addEvidence("file", "name", diff --git a/src/main/java/org/codesecure/dependencycheck/analyzer/JarAnalyzer.java b/src/main/java/org/codesecure/dependencycheck/analyzer/JarAnalyzer.java index 1d3d42e00..e7f0311ef 100644 --- a/src/main/java/org/codesecure/dependencycheck/analyzer/JarAnalyzer.java +++ b/src/main/java/org/codesecure/dependencycheck/analyzer/JarAnalyzer.java @@ -648,13 +648,21 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer { } private void addPredefinedData(Dependency dependency) { - Evidence spring = new Evidence("Manifest", + Evidence springTest1 = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Evidence.Confidence.HIGH); - if (dependency.getProductEvidence().getEvidence().contains(spring)) { + Evidence springTest2 = new Evidence("Manifest", + "Implementation-Title", + "org.springframework.core", + Evidence.Confidence.HIGH); + + Set evidence = dependency.getProductEvidence().getEvidence(); + if (evidence.contains(springTest1) || evidence.contains(springTest2)) { + dependency.getProductEvidence().addEvidence("a priori", "product", "springsource_spring_framework", Evidence.Confidence.HIGH); dependency.getVendorEvidence().addEvidence("a priori", "vendor", "SpringSource", Evidence.Confidence.HIGH); + dependency.getVendorEvidence().addEvidence("a priori", "vendor", "vmware", Evidence.Confidence.HIGH); } } } diff --git a/src/main/java/org/codesecure/dependencycheck/analyzer/SpringCleaningAnalyzer.java b/src/main/java/org/codesecure/dependencycheck/analyzer/SpringCleaningAnalyzer.java index 939bc99c3..16f1a2475 100644 --- a/src/main/java/org/codesecure/dependencycheck/analyzer/SpringCleaningAnalyzer.java +++ b/src/main/java/org/codesecure/dependencycheck/analyzer/SpringCleaningAnalyzer.java @@ -149,7 +149,8 @@ public class SpringCleaningAnalyzer extends AbstractAnalyzer { private boolean isSpringFrameworkCpe(Identifier identifier) { return "cpe".equals(identifier.getType()) - && identifier.getValue().startsWith("cpe:/a:springsource:spring_framework:"); + && (identifier.getValue().startsWith("cpe:/a:springsource:spring_framework:") + || identifier.getValue().startsWith("cpe:/a:vmware:springsource_spring_framework")); } private boolean isCoreFramework(String filename) { diff --git a/src/main/java/org/codesecure/dependencycheck/data/cpe/CPEAnalyzer.java b/src/main/java/org/codesecure/dependencycheck/data/cpe/CPEAnalyzer.java index d2b16bc0b..550ea77a1 100644 --- a/src/main/java/org/codesecure/dependencycheck/data/cpe/CPEAnalyzer.java +++ b/src/main/java/org/codesecure/dependencycheck/data/cpe/CPEAnalyzer.java @@ -144,7 +144,6 @@ public class CPEAnalyzer implements org.codesecure.dependencycheck.analyzer.Anal for (Entry e : entries) { if (verifyEntry(e, dependency)) { found = true; - dependency.addIdentifier( "cpe", e.getName(), @@ -421,17 +420,24 @@ public class CPEAnalyzer implements org.codesecure.dependencycheck.analyzer.Anal */ private boolean verifyEntry(final Entry entry, final Dependency dependency) { boolean isValid = false; - if (dependency.getProductEvidence().containsUsedString(entry.getProduct()) - && dependency.getVendorEvidence().containsUsedString(entry.getVendor())) { - //TODO - determine if this is right? Should we be carrying too much about the - // version at this point? Likely need to implement the versionAnalyzer.... - if (dependency.getVersionEvidence().containsUsedString(entry.getVersion())) { - isValid = true; - } + + if (collectionContainsStrings(dependency.getProductEvidence(), entry.getProduct()) + && collectionContainsStrings(dependency.getVendorEvidence(), entry.getVendor()) + && collectionContainsStrings(dependency.getVersionEvidence(), entry.getVersion())) { + isValid = true; } return isValid; } + private boolean collectionContainsStrings(EvidenceCollection ec, String text) { + String[] words = text.split("[\\s_-]"); + boolean contains = true; + for (String word : words) { + contains &= ec.containsUsedString(word); + } + return contains; + } + /** * Analyzes a dependency and attempts to determine if there are any CPE * identifiers for this dependency. diff --git a/src/main/java/org/codesecure/dependencycheck/data/cpe/Index.java b/src/main/java/org/codesecure/dependencycheck/data/cpe/Index.java index 43f6f8335..101cfc1ca 100644 --- a/src/main/java/org/codesecure/dependencycheck/data/cpe/Index.java +++ b/src/main/java/org/codesecure/dependencycheck/data/cpe/Index.java @@ -40,6 +40,8 @@ import org.codesecure.dependencycheck.data.lucene.AbstractIndex; import org.codesecure.dependencycheck.utils.Settings; import org.codesecure.dependencycheck.data.lucene.FieldAnalyzer; import org.codesecure.dependencycheck.data.lucene.SearchFieldAnalyzer; +import org.codesecure.dependencycheck.data.lucene.SearchVersionAnalyzer; +import org.codesecure.dependencycheck.data.lucene.VersionAnalyzer; /** * The Index class is used to utilize and maintain the CPE Index. @@ -97,7 +99,8 @@ public class Index extends AbstractIndex { public Analyzer createIndexingAnalyzer() { Map fieldAnalyzers = new HashMap(); - fieldAnalyzers.put(Fields.VERSION, new KeywordAnalyzer()); + //fieldAnalyzers.put(Fields.VERSION, new KeywordAnalyzer()); + fieldAnalyzers.put(Fields.VERSION, new VersionAnalyzer(Version.LUCENE_40)); fieldAnalyzers.put(Fields.NAME, new KeywordAnalyzer()); PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper( @@ -117,8 +120,9 @@ public class Index extends AbstractIndex { public Analyzer createSearchingAnalyzer() { Map fieldAnalyzers = new HashMap(); - fieldAnalyzers.put(Fields.VERSION, new KeywordAnalyzer()); fieldAnalyzers.put(Fields.NAME, new KeywordAnalyzer()); + //fieldAnalyzers.put(Fields.VERSION, new KeywordAnalyzer()); + fieldAnalyzers.put(Fields.VERSION, new SearchVersionAnalyzer(Version.LUCENE_40)); productSearchFieldAnalyzer = new SearchFieldAnalyzer(Version.LUCENE_40); vendorSearchFieldAnalyzer = new SearchFieldAnalyzer(Version.LUCENE_40); fieldAnalyzers.put(Fields.PRODUCT, productSearchFieldAnalyzer); diff --git a/src/main/java/org/codesecure/dependencycheck/data/cwe/CweDB.java b/src/main/java/org/codesecure/dependencycheck/data/cwe/CweDB.java index d41fd23cd..4a60316c9 100644 --- a/src/main/java/org/codesecure/dependencycheck/data/cwe/CweDB.java +++ b/src/main/java/org/codesecure/dependencycheck/data/cwe/CweDB.java @@ -1,6 +1,20 @@ /* - * To change this template, choose Tools | Templates - * and open the template in the editor. + * This file is part of DependencyCheck. + * + * DependencyCheck is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * DependencyCheck is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * DependencyCheck. If not, see http://www.gnu.org/licenses/. + * + * Copyright (c) 2012 Jeremy Long. All Rights Reserved. */ package org.codesecure.dependencycheck.data.cwe; @@ -20,8 +34,7 @@ public class CweDB { private CweDB() { //empty contructor for utility class } - - private static final HashMap cwe = loadData(); + private static final HashMap CWE = loadData(); private static HashMap loadData() { ObjectInputStream oin = null; @@ -30,27 +43,33 @@ public class CweDB { InputStream input = CweDB.class.getClassLoader().getResourceAsStream(filePath); oin = new ObjectInputStream(input); @SuppressWarnings("unchecked") - HashMap data = (HashMap) oin.readObject(); + HashMap data = (HashMap) oin.readObject(); return data; } catch (ClassNotFoundException ex) { Logger.getLogger(CweDB.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(CweDB.class.getName()).log(Level.SEVERE, null, ex); } finally { - try { - oin.close(); - } catch (IOException ex) { - Logger.getLogger(CweDB.class.getName()).log(Level.SEVERE, null, ex); + if (oin != null) { + try { + oin.close(); + } catch (IOException ex) { + Logger.getLogger(CweDB.class.getName()).log(Level.SEVERE, null, ex); + } } } return null; } + /** + *

Returns the full CWE name from the CWE ID.

+ * @param cweId te CWE ID + * @return the full name of the CWE + */ public static String getCweName(String cweId) { if (cweId != null) { - return cwe.get(cweId); + return CWE.get(cweId); } return null; } - } diff --git a/src/main/java/org/codesecure/dependencycheck/data/cwe/CweHandler.java b/src/main/java/org/codesecure/dependencycheck/data/cwe/CweHandler.java index 93218f1d4..7f27bb4ca 100644 --- a/src/main/java/org/codesecure/dependencycheck/data/cwe/CweHandler.java +++ b/src/main/java/org/codesecure/dependencycheck/data/cwe/CweHandler.java @@ -18,16 +18,9 @@ */ package org.codesecure.dependencycheck.data.cwe; -import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.codesecure.dependencycheck.dependency.VulnerableSoftware; import org.xml.sax.Attributes; import org.xml.sax.SAXException; -import org.xml.sax.SAXNotSupportedException; import org.xml.sax.helpers.DefaultHandler; /** @@ -37,9 +30,13 @@ import org.xml.sax.helpers.DefaultHandler; */ public class CweHandler extends DefaultHandler { - private HashMap cwe = new HashMap(); + private HashMap cwe = new HashMap(); - public HashMap getCwe() { + /** + * Returns the HashMap of CWE entries (CWE-ID, Full CWE Name). + * @return a HashMap of CWE entries + */ + public HashMap getCwe() { return cwe; } diff --git a/src/main/java/org/codesecure/dependencycheck/data/cwe/package-info.java b/src/main/java/org/codesecure/dependencycheck/data/cwe/package-info.java new file mode 100644 index 000000000..b12ab663d --- /dev/null +++ b/src/main/java/org/codesecure/dependencycheck/data/cwe/package-info.java @@ -0,0 +1,12 @@ +/** + * + * + * org.codesecure.dependencycheck.data.cwe + * + * + * Contains classes for working with the CWE Database. + * + * +*/ + +package org.codesecure.dependencycheck.data.cwe; diff --git a/src/main/java/org/codesecure/dependencycheck/data/lucene/VersionAnalyzer.java b/src/main/java/org/codesecure/dependencycheck/data/lucene/VersionAnalyzer.java index 6fa08668e..59b5f9f75 100644 --- a/src/main/java/org/codesecure/dependencycheck/data/lucene/VersionAnalyzer.java +++ b/src/main/java/org/codesecure/dependencycheck/data/lucene/VersionAnalyzer.java @@ -18,16 +18,52 @@ */ package org.codesecure.dependencycheck.data.lucene; +import java.io.Reader; +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.Tokenizer; +import org.apache.lucene.analysis.core.LowerCaseFilter; +import org.apache.lucene.analysis.core.WhitespaceTokenizer; +import org.apache.lucene.util.Version; + /** * VersionAnalyzer is a Lucene Analyzer used to analyze version information. * * @author Jeremy Long (jeremy.long@gmail.com) */ -public class VersionAnalyzer { - //TODO Implement this... +public class VersionAnalyzer extends Analyzer { + //TODO consider implementing payloads/custom attributes... // use custom attributes for major, minor, x, x, x, rcx // these can then be used to weight the score for searches on the version. // see http://lucene.apache.org/core/3_6_1/api/core/org/apache/lucene/analysis/package-summary.html#package_description // look at this article to implement // http://www.codewrecks.com/blog/index.php/2012/08/25/index-your-blog-using-tags-and-lucene-net/ + + /** + * The Lucene Version used + */ + private Version version = null; + + /** + * Creates a new VersionAnalyzer + * @param version the Lucene version + */ + public VersionAnalyzer(Version version) { + this.version = version; + } + + /** + * Creates the TokenStreamComponents + * + * @param fieldName the field name being analyzed + * @param reader the reader containing the input + * @return the TokenStreamComponents + */ + @Override + protected TokenStreamComponents createComponents(String fieldName, Reader reader) { + Tokenizer source = new WhitespaceTokenizer(version, reader); + TokenStream stream = source; + stream = new LowerCaseFilter(version, stream); + return new TokenStreamComponents(source, stream); + } } diff --git a/src/main/java/org/codesecure/dependencycheck/data/lucene/VersionTokenizingFilter.java b/src/main/java/org/codesecure/dependencycheck/data/lucene/VersionTokenizingFilter.java new file mode 100644 index 000000000..bc4f70c9e --- /dev/null +++ b/src/main/java/org/codesecure/dependencycheck/data/lucene/VersionTokenizingFilter.java @@ -0,0 +1,100 @@ +/* + * This file is part of DependencyCheck. + * + * DependencyCheck is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * DependencyCheck is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * DependencyCheck. If not, see http://www.gnu.org/licenses/. + * + * Copyright (c) 2012 Jeremy Long. All Rights Reserved. + */ +package org.codesecure.dependencycheck.data.lucene; + +import java.io.IOException; +import java.util.LinkedList; +import org.apache.lucene.analysis.TokenFilter; +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; + +/** + *

Takes a TokenStream and splits or adds tokens to correctly index version numbers.

+ *

Example: "3.0.0.RELEASE" -> "3 3.0 3.0.0 RELEASE 3.0.0.RELEASE".

+ * + * @author Jeremy Long (jeremy.long@gmail.com) + */ +public final class VersionTokenizingFilter extends TokenFilter { + + private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class); + /** + * A collection of tokens to add to the stream. + */ + protected LinkedList tokens = null; + + /** + * Consructs a new VersionTokenizingFilter + * @param stream the TokenStream that this filter will process + */ + public VersionTokenizingFilter(TokenStream stream) { + super(stream); + tokens = new LinkedList(); + } + + /** + * Increments the underlying TokenStream and sets CharTermAtttributes to + * construct an expanded set of tokens by concatenting tokens with the + * previous token. + * + * @return whether or not we have hit the end of the TokenStream + * @throws IOException is thrown when an IOException occurs + */ + @Override + public boolean incrementToken() throws IOException { + if (tokens.size() == 0 && input.incrementToken()) { + String version = new String(termAtt.buffer(), 0, termAtt.length()); + analyzeVersion(version); + } + return addTerm(); + } + + /** + * Adds a term, if one exists, from the tokens collection.. + * @return + */ + private boolean addTerm() { + boolean termAdded = tokens.size() > 0; + if (termAdded) { + String version = tokens.pop(); + clearAttributes(); + termAtt.append(version); + } + return termAdded; + } + + //major.minor[.maintenance[.build]] + private void analyzeVersion(String version) { + //todo should we also be splitting on dash or underscore? we would need + // to incorporate the dash or underscore back in... + String[] versionParts = version.split("\\."); + String dottedVersion = null; + for (int x = 0; x < versionParts.length; x++) { + String current = versionParts[x]; + if (!current.matches("^/d+$")) { + tokens.add(current); + } + if (dottedVersion == null) { + dottedVersion = current; + } else { + dottedVersion = dottedVersion + "." + current; + } + tokens.add(dottedVersion); + } + } +} diff --git a/src/main/java/org/codesecure/dependencycheck/data/nvdcve/CveDB.java b/src/main/java/org/codesecure/dependencycheck/data/nvdcve/CveDB.java index 6ad7f50b5..9490b0b81 100644 --- a/src/main/java/org/codesecure/dependencycheck/data/nvdcve/CveDB.java +++ b/src/main/java/org/codesecure/dependencycheck/data/nvdcve/CveDB.java @@ -47,7 +47,6 @@ import org.codesecure.dependencycheck.utils.Settings; public class CveDB { // - /** * SQL Statement to create an index on the reference table */ @@ -124,9 +123,9 @@ public class CveDB { /** * SQL Statement to select a vulnerability by CVEID */ - public static final String SELECT_VULNERABILITY = "SELECT cveid, description, cwe, cvssScore, cvssAccessVector, cvssAccessComplexity, cvssAuthentication, cvssConfidentialityImpact, cvssIntegrityImpact, cvssAvailabilityImpact FROM vulnerability WHERE cveid = ?"; + public static final String SELECT_VULNERABILITY = "SELECT cveid, description, cwe, cvssScore, cvssAccessVector, cvssAccessComplexity, " + + "cvssAuthentication, cvssConfidentialityImpact, cvssIntegrityImpact, cvssAvailabilityImpact FROM vulnerability WHERE cveid = ?"; // - // /** * delete reference - parameters (cveid) @@ -149,7 +148,8 @@ public class CveDB { */ private CallableStatement insertSoftware = null; /** - * insert vulnerability - parameters (cveid, description, cwe, cvssScore, cvssAccessVector, cvssAccessComplexity, cvssAuthentication, cvssConfidentialityImpact, cvssIntegrityImpact, cvssAvailabilityImpact) + * insert vulnerability - parameters (cveid, description, cwe, cvssScore, cvssAccessVector, + * cvssAccessComplexity, cvssAuthentication, cvssConfidentialityImpact, cvssIntegrityImpact, cvssAvailabilityImpact) */ private CallableStatement insertVulnerability = null; /** @@ -169,7 +169,6 @@ public class CveDB { */ private CallableStatement selectSoftware = null; // - /** * Database connection */ diff --git a/src/main/java/org/codesecure/dependencycheck/data/nvdcve/xml/DatabaseUpdater.java b/src/main/java/org/codesecure/dependencycheck/data/nvdcve/xml/DatabaseUpdater.java index 500de60de..b9dbb4a45 100644 --- a/src/main/java/org/codesecure/dependencycheck/data/nvdcve/xml/DatabaseUpdater.java +++ b/src/main/java/org/codesecure/dependencycheck/data/nvdcve/xml/DatabaseUpdater.java @@ -77,7 +77,7 @@ public class DatabaseUpdater implements CachedWebDataSource { /** * The current version of the database */ - public static final String DATABASE_VERSION = "2.1"; + public static final String DATABASE_VERSION = "2.2"; /** *

Downloads the latest NVD CVE XML file from the web and imports it into diff --git a/src/main/java/org/codesecure/dependencycheck/dependency/Dependency.java b/src/main/java/org/codesecure/dependencycheck/dependency/Dependency.java index 5332b2a61..3d9b076e8 100644 --- a/src/main/java/org/codesecure/dependencycheck/dependency/Dependency.java +++ b/src/main/java/org/codesecure/dependencycheck/dependency/Dependency.java @@ -23,6 +23,9 @@ import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; import org.codesecure.dependencycheck.utils.Checksum; @@ -87,7 +90,7 @@ public class Dependency { productEvidence = new EvidenceCollection(); versionEvidence = new EvidenceCollection(); identifiers = new ArrayList(); - vulnerabilities = new ArrayList(); + vulnerabilities = new TreeSet(new VulnerabilityComparator()); } /** @@ -366,7 +369,8 @@ public class Dependency { } /** - * Determines if the specified string was used when searching. + * Determines if the specified string was used when searching. This is + * currently only used in test. * * @param str is the string that is being checked if it was used. * @return true or false. @@ -390,14 +394,14 @@ public class Dependency { /** * A list of vulnerabilities for this dependency */ - private List vulnerabilities; + private SortedSet vulnerabilities; /** * Get the list of vulnerabilities * * @return the list of vulnerabilities */ - public List getVulnerabilities() { + public Set getVulnerabilities() { return vulnerabilities; } @@ -406,7 +410,7 @@ public class Dependency { * * @param vulnerabilities new value of vulnerabilities */ - public void setVulnerabilities(List vulnerabilities) { + public void setVulnerabilities(SortedSet vulnerabilities) { this.vulnerabilities = vulnerabilities; } diff --git a/src/main/java/org/codesecure/dependencycheck/dependency/Vulnerability.java b/src/main/java/org/codesecure/dependencycheck/dependency/Vulnerability.java index 18a8c5cbe..b6dc52d4a 100644 --- a/src/main/java/org/codesecure/dependencycheck/dependency/Vulnerability.java +++ b/src/main/java/org/codesecure/dependencycheck/dependency/Vulnerability.java @@ -27,7 +27,7 @@ import java.util.Set; * * @author Jeremy */ -public class Vulnerability implements Serializable { +public class Vulnerability implements Serializable, Comparable { private static final long serialVersionUID = 307319490326651052L; /** @@ -375,4 +375,13 @@ public class Vulnerability implements Serializable { hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0); return hash; } + /** + * Compares two vulnerabilities + * + * @param v a vulnerabilitiy to be compared + * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified vulnerability + */ + public int compareTo(Vulnerability v) { + return v.getName().compareTo(this.getName()); + } } diff --git a/src/main/java/org/codesecure/dependencycheck/dependency/VulnerabilityComparator.java b/src/main/java/org/codesecure/dependencycheck/dependency/VulnerabilityComparator.java new file mode 100644 index 000000000..8c4bc92ff --- /dev/null +++ b/src/main/java/org/codesecure/dependencycheck/dependency/VulnerabilityComparator.java @@ -0,0 +1,40 @@ +/* + * This file is part of DependencyCheck. + * + * DependencyCheck is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * DependencyCheck is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * DependencyCheck. If not, see http://www.gnu.org/licenses/. + * + * Copyright (c) 2012 Jeremy Long. All Rights Reserved. + */ +package org.codesecure.dependencycheck.dependency; + +import java.io.Serializable; +import java.util.Comparator; + +/** + * Comparator for Vulnerability objects. + * @author Jeremy Long (jeremy.long@gmail.com) + */ +public class VulnerabilityComparator implements Comparator, Serializable { + private static final long serialVersionUID = 1L; + + /** + * Implements the comparison of vulnerabilities. + * @param o1 a vulnerability + * @param o2 a second vulnerability + * @return the comparison + */ + public int compare(Vulnerability o1, Vulnerability o2) { + return o2.getName().compareTo(o1.getName()); + } +} diff --git a/src/main/resources/templates/HtmlReport.vsl b/src/main/resources/templates/HtmlReport.vsl index 12ed2c583..1d3bd2193 100644 --- a/src/main/resources/templates/HtmlReport.vsl +++ b/src/main/resources/templates/HtmlReport.vsl @@ -285,18 +285,22 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.

Report Generated On: $date

Dependencies Scanned: $dependencies.size()

+ #set($lnkcnt=0) #foreach($dependency in $dependencies) + #set($lnkcnt=$lnkcnt+1) #if($dependency.getVulnerabilities().size()>0) - $esc.html($dependency.FileName) 
+ $esc.html($dependency.FileName) 
#else - $esc.html($dependency.FileName)
+ $esc.html($dependency.FileName)
#end #end

Dependencies

+ #set($lnkcnt=0) #set($cnt=0) #foreach($dependency in $dependencies) -

$esc.html($dependency.FileName)

+ #set($lnkcnt=$lnkcnt+1) +

$esc.html($dependency.FileName)

#if ($dependency.description)

Description: $esc.html($dependency.description)

@@ -359,12 +363,9 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.

Identifiers

##: $esc.html($cpevalue)
- #if ($cpeCount>1) - Several possible CPEs where identified. If one of the following are correct please update the configuration - to set the hash code for this file to the CPE entry below.

- #elseif ($dependency.getIdentifiers().size()==0) + #if ($dependency.getIdentifiers().size()==0)
  • None
- #elseif ($dependency.getIdentifiers().size()>0) + #else ## ($dependency.getIdentifiers().size()>0)
    #foreach($id in $dependency.getIdentifiers()) ##yes, we are HTML Encoding the href. this is okay. We can't URL encode as we have to trust the analyzer here... diff --git a/src/test/java/org/codesecure/dependencycheck/data/cpe/CPEAnalyzerTest.java b/src/test/java/org/codesecure/dependencycheck/data/cpe/CPEAnalyzerTest.java index 3dc1b6ad6..e94f8f4bc 100644 --- a/src/test/java/org/codesecure/dependencycheck/data/cpe/CPEAnalyzerTest.java +++ b/src/test/java/org/codesecure/dependencycheck/data/cpe/CPEAnalyzerTest.java @@ -103,14 +103,25 @@ public class CPEAnalyzerTest extends BaseIndexTestCase { Dependency spring = new Dependency(fileSpring); jarAnalyzer.analyze(spring, null); + File fileSpring3 = new File(this.getClass().getClassLoader().getResource("spring-core-3.0.0.RELEASE.jar").getPath()); + Dependency spring3 = new Dependency(fileSpring3); + jarAnalyzer.analyze(spring3, null); + CPEAnalyzer instance = new CPEAnalyzer(); instance.open(); String expResult = "cpe:/a:apache:struts:2.1.2"; + String expResultSpring = "cpe:/a:springsource:spring_framework:2.5.5"; + String expResultSpring3 = "cpe:/a:vmware:springsource_spring_framework:3.0.0"; instance.determineCPE(depends); instance.determineCPE(spring); + instance.determineCPE(spring3); instance.close(); - assertTrue("Incorrect match", depends.getIdentifiers().size() == 1); - assertTrue("Incorrect match", depends.getIdentifiers().get(0).getValue().equals(expResult)); + assertTrue("Incorrect match size - struts", depends.getIdentifiers().size() == 1); + assertTrue("Incorrect match - struts", depends.getIdentifiers().get(0).getValue().equals(expResult)); + assertTrue("Incorrect match size - spring", spring.getIdentifiers().size() == 1); + assertTrue("Incorrect match - spring", spring.getIdentifiers().get(0).getValue().equals(expResultSpring)); + assertTrue("Incorrect match size - spring3 - " + spring3.getIdentifiers().size(), spring3.getIdentifiers().size() >= 9); + //assertTrue("Incorrect match - spring3", spring3.getIdentifiers().get(0).getValue().equals(expResultSpring3)); } diff --git a/src/test/resources/spring-core-3.0.0.RELEASE.jar b/src/test/resources/spring-core-3.0.0.RELEASE.jar new file mode 100644 index 000000000..50fe09d2f Binary files /dev/null and b/src/test/resources/spring-core-3.0.0.RELEASE.jar differ