diff --git a/README.txt b/README.txt
index c5fe133e9..59883f98f 100644
--- a/README.txt
+++ b/README.txt
@@ -7,10 +7,10 @@ If found, it will generate a report linking to the associated CVE entries.
Usage:
$ mvn package
$ cd target
-$ java -jar DependencyCheck-0.2.3.jar -h
-$ java -jar DependencyCheck-0.2.3.jar -a Testing -out . -scan ./test-classes/org.mortbay.jetty.jar -scan ./test-classes/struts2-core-2.1.2.jar -scan ./lib
+$ java -jar DependencyCheck-0.2.3.1.jar -h
+$ java -jar DependencyCheck-0.2.3.1.jar -a Testing -out . -scan ./test-classes/org.mortbay.jetty.jar -scan ./test-classes/struts2-core-2.1.2.jar -scan ./lib
-Then load the resulting 'Testing.html' into your favorite browser.
+Then load the resulting 'DependencyCheck-Report.html' into your favorite browser.
Author: Jeremy Long (jeremy.long@gmail.com)
diff --git a/pom.xml b/pom.xml
index e81a40003..6122e2ad9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@ along with DependencyCheck. If not, see .
org.codesecure
DependencyCheck
- 0.2.3
+ 0.2.3.1
jar
DependencyCheck
@@ -100,7 +100,7 @@ along with DependencyCheck. If not, see .
maven-javadoc-plugin
2.8.1
- Copyright © 2012 Jeremy Long. All Rights Reserved.
+ Copyright© 2012 Jeremy Long. All Rights Reserved.
@@ -451,5 +451,14 @@ along with DependencyCheck. If not, see .
hawtdb
1.6
-->
+
+
+
+
diff --git a/src/main/java/org/codesecure/dependencycheck/App.java b/src/main/java/org/codesecure/dependencycheck/App.java
index ca24abc73..9f726c0dc 100644
--- a/src/main/java/org/codesecure/dependencycheck/App.java
+++ b/src/main/java/org/codesecure/dependencycheck/App.java
@@ -28,7 +28,6 @@ import java.util.logging.LogManager;
import java.util.logging.Logger;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.cli.ParseException;
-import org.codesecure.dependencycheck.analyzer.AnalysisPhase;
import org.codesecure.dependencycheck.data.cpe.xml.Importer;
import org.codesecure.dependencycheck.reporting.ReportGenerator;
import org.codesecure.dependencycheck.dependency.Dependency;
diff --git a/src/main/java/org/codesecure/dependencycheck/Engine.java b/src/main/java/org/codesecure/dependencycheck/Engine.java
index 11a8a1b42..1eb2c9b9d 100644
--- a/src/main/java/org/codesecure/dependencycheck/Engine.java
+++ b/src/main/java/org/codesecure/dependencycheck/Engine.java
@@ -195,7 +195,7 @@ public class Engine {
try {
a.initialize();
} catch (Exception ex) {
- Logger.getLogger(Engine.class.getName()).log(Level.SEVERE,
+ Logger.getLogger(Engine.class.getName()).log(Level.SEVERE,
"Exception occured initializing " + a.getName() + ".", ex);
try {
a.close();
@@ -255,7 +255,7 @@ public class Engine {
try {
source.update();
} catch (UpdateException ex) {
- Logger.getLogger(Engine.class.getName()).log(Level.SEVERE,
+ Logger.getLogger(Engine.class.getName()).log(Level.SEVERE,
"Unable to update " + source.getClass().getName(), ex);
}
}
diff --git a/src/main/java/org/codesecure/dependencycheck/analyzer/JarAnalyzer.java b/src/main/java/org/codesecure/dependencycheck/analyzer/JarAnalyzer.java
index 6e2bb5ab2..db5cd4597 100644
--- a/src/main/java/org/codesecure/dependencycheck/analyzer/JarAnalyzer.java
+++ b/src/main/java/org/codesecure/dependencycheck/analyzer/JarAnalyzer.java
@@ -186,6 +186,7 @@ public class JarAnalyzer extends AbstractAnalyzer {
parseManifest(dependency);
analyzePackageNames(dependency);
analyzePOM(dependency);
+ addPredefinedData(dependency);
} catch (IOException ex) {
throw new AnalysisException("Exception occured reading the JAR file.", ex);
} catch (JAXBException ex) {
@@ -615,4 +616,15 @@ public class JarAnalyzer extends AbstractAnalyzer {
sb.append(text.substring(end + 1));
return interpolateString(sb.toString(), properties); //yes yes, this should be a loop...
}
+
+ private void addPredefinedData(Dependency dependency) {
+ Evidence spring = new Evidence("Manifest",
+ "Implementation-Title",
+ "Spring Framework",
+ Evidence.Confidence.HIGH);
+
+ if (dependency.getProductEvidence().getEvidence().contains(spring)) {
+ dependency.getVendorEvidence().addEvidence("a priori", "vendor", "SpringSource", Evidence.Confidence.HIGH);
+ }
+ }
}
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 8a8306c8f..822f54031 100644
--- a/src/main/java/org/codesecure/dependencycheck/data/cpe/CPEAnalyzer.java
+++ b/src/main/java/org/codesecure/dependencycheck/data/cpe/CPEAnalyzer.java
@@ -149,23 +149,11 @@ public class CPEAnalyzer implements org.codesecure.dependencycheck.analyzer.Anal
Confidence versionConf = Confidence.HIGH;
String vendors = addEvidenceWithoutDuplicateTerms("", dependency.getVendorEvidence(), vendorConf);
- //dependency.getVendorEvidence().toString(vendorConf);
-// if ("".equals(vendors)) {
-// vendors = STRING_THAT_WILL_NEVER_BE_IN_THE_INDEX;
-// }
String products = addEvidenceWithoutDuplicateTerms("", dependency.getProductEvidence(), productConf);
- ///dependency.getProductEvidence().toString(productConf);
-// if ("".equals(products)) {
-// products = STRING_THAT_WILL_NEVER_BE_IN_THE_INDEX;
-// }
String versions = addEvidenceWithoutDuplicateTerms("", dependency.getVersionEvidence(), versionConf);
- //dependency.getVersionEvidence().toString(versionConf);
-// if ("".equals(versions)) {
-// versions = STRING_THAT_WILL_NEVER_BE_IN_THE_INDEX;
-// }
boolean found = false;
- int cnt = 0;
+ int ctr = 0;
do {
List entries = searchCPE(vendors, products, versions, dependency.getProductEvidence().getWeighting(),
dependency.getVendorEvidence().getWeighting());
@@ -186,14 +174,14 @@ public class CPEAnalyzer implements org.codesecure.dependencycheck.analyzer.Anal
if (!found) {
- int round = cnt % 3;
+ int round = ctr % 3;
if (round == 0) {
vendorConf = reduceConfidence(vendorConf);
if (dependency.getVendorEvidence().contains(vendorConf)) {
//vendors += " " + dependency.getVendorEvidence().toString(vendorConf);
vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), vendorConf);
} else {
- cnt += 1;
+ ctr += 1;
round += 1;
}
}
@@ -203,7 +191,7 @@ public class CPEAnalyzer implements org.codesecure.dependencycheck.analyzer.Anal
//products += " " + dependency.getProductEvidence().toString(productConf);
products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), productConf);
} else {
- cnt += 1;
+ ctr += 1;
round += 1;
}
}
@@ -215,7 +203,7 @@ public class CPEAnalyzer implements org.codesecure.dependencycheck.analyzer.Anal
}
}
}
- } while (!found && (++cnt) < 9);
+ } while (!found && (++ctr) < 9);
}
/**
diff --git a/src/main/java/org/codesecure/dependencycheck/data/cpe/Entry.java b/src/main/java/org/codesecure/dependencycheck/data/cpe/Entry.java
index ce015763f..d42b8e552 100644
--- a/src/main/java/org/codesecure/dependencycheck/data/cpe/Entry.java
+++ b/src/main/java/org/codesecure/dependencycheck/data/cpe/Entry.java
@@ -45,17 +45,12 @@ public class Entry {
public static Entry parse(Document doc) {
Entry entry = new Entry();
try {
- entry.setName(doc.get(Fields.NAME));
+ entry.parseName(doc.get(Fields.NAME));
entry.setTitle(doc.get(Fields.TITLE));
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(Entry.class.getName()).log(Level.SEVERE, null, ex);
entry.name = doc.get(Fields.NAME);
}
-// entry.vendor = doc.get(Fields.VENDOR);
-// entry.version = doc.get(Fields.VERSION);
-// //entry.revision = doc.get(Fields.REVISION);
-// entry.product = doc.get(Fields.TITLE);
-// entry.nvdId = doc.get(Fields.NVDID);
return entry;
}
/**
@@ -95,15 +90,12 @@ public class Entry {
}
/**
- * Set the value of name and calls parseName to obtain the
- * vendor:product:version:revision
+ * Set the value of name
*
* @param name new value of name
- * @throws UnsupportedEncodingException should never be thrown...
*/
- public void setName(String name) throws UnsupportedEncodingException {
+ public void setName(String name) {
this.name = name;
- parseName();
}
/**
* The status of the CPE Entry.
@@ -310,15 +302,17 @@ public class Entry {
* Results in:
- Vendor: apache
- Product: struts
* - Version: 1.1
- Revision: rc2
*
+ * @param cpeName the cpe name
* @throws UnsupportedEncodingException should never be thrown...
*/
- private void parseName() throws UnsupportedEncodingException {
- if (name != null && name.length() > 7) {
- String[] data = name.substring(7).split(":");
+ public void parseName(String cpeName) throws UnsupportedEncodingException {
+ this.name = cpeName;
+ if (cpeName != null && cpeName.length() > 7) {
+ String[] data = cpeName.substring(7).split(":");
if (data.length >= 1) {
- vendor = URLDecoder.decode(data[0], "UTF-8");
+ vendor = URLDecoder.decode(data[0], "UTF-8").replaceAll("[_-]", " ");
if (data.length >= 2) {
- product = URLDecoder.decode(data[1], "UTF-8");
+ product = URLDecoder.decode(data[1], "UTF-8").replaceAll("[_-]", " ");
if (data.length >= 3) {
version = URLDecoder.decode(data[2], "UTF-8");
if (data.length >= 4) {
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 6a057de12..b52e0e4cb 100644
--- a/src/main/java/org/codesecure/dependencycheck/data/cpe/Index.java
+++ b/src/main/java/org/codesecure/dependencycheck/data/cpe/Index.java
@@ -100,6 +100,11 @@ public class Index extends AbstractIndex implements CachedWebDataSource {
}
File path = new File(exePath.getCanonicalFile() + File.separator + fileName);
path = new File(path.getCanonicalPath());
+ if (!path.exists()) {
+ if (!path.mkdirs()) {
+ throw new IOException("Unable to create CPE Data directory");
+ }
+ }
return path;
}
@@ -113,6 +118,7 @@ public class Index extends AbstractIndex implements CachedWebDataSource {
Map fieldAnalyzers = new HashMap();
fieldAnalyzers.put(Fields.VERSION, new KeywordAnalyzer());
+ fieldAnalyzers.put(Fields.NAME, new KeywordAnalyzer());
PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper(
new StandardAnalyzer(Version.LUCENE_35), fieldAnalyzers);
diff --git a/src/main/java/org/codesecure/dependencycheck/data/cpe/xml/CPEHandler.java b/src/main/java/org/codesecure/dependencycheck/data/cpe/xml/CPEHandler.java
index 085b15b63..076bf406c 100644
--- a/src/main/java/org/codesecure/dependencycheck/data/cpe/xml/CPEHandler.java
+++ b/src/main/java/org/codesecure/dependencycheck/data/cpe/xml/CPEHandler.java
@@ -66,7 +66,7 @@ public class CPEHandler extends DefaultHandler {
skip = (temp != null && temp.equals("true"));
try {
if (!skip && name.startsWith("cpe:/a:")) {
- entry.setName(name);
+ entry.parseName(name);
} else {
skip = true;
}
diff --git a/src/main/java/org/codesecure/dependencycheck/data/cpe/xml/Indexer.java b/src/main/java/org/codesecure/dependencycheck/data/cpe/xml/Indexer.java
index 4f350fa66..39870bf0e 100644
--- a/src/main/java/org/codesecure/dependencycheck/data/cpe/xml/Indexer.java
+++ b/src/main/java/org/codesecure/dependencycheck/data/cpe/xml/Indexer.java
@@ -27,7 +27,6 @@ import org.apache.lucene.index.Term;
import org.codesecure.dependencycheck.data.cpe.Entry;
import org.codesecure.dependencycheck.data.cpe.Fields;
import org.codesecure.dependencycheck.data.cpe.Index;
-import org.codesecure.dependencycheck.data.lucene.LuceneUtils;
/**
* The Indexer is used to convert a CPE Entry, retrieved from the CPE XML file,
@@ -46,7 +45,8 @@ public class Indexer extends Index implements EntrySaveDelegate {
*/
public void saveEntry(Entry entry) throws CorruptIndexException, IOException {
Document doc = convertEntryToDoc(entry);
- Term term = new Term(Fields.NVDID, LuceneUtils.escapeLuceneQuery(entry.getNvdId()));
+ //Term term = new Term(Fields.NVDID, LuceneUtils.escapeLuceneQuery(entry.getNvdId()));
+ Term term = new Term(Fields.NAME, entry.getName());
indexWriter.updateDocument(term, doc);
}
diff --git a/src/main/java/org/codesecure/dependencycheck/data/nvdcve/Index.java b/src/main/java/org/codesecure/dependencycheck/data/nvdcve/Index.java
index d544acd60..ebf5c5974 100644
--- a/src/main/java/org/codesecure/dependencycheck/data/nvdcve/Index.java
+++ b/src/main/java/org/codesecure/dependencycheck/data/nvdcve/Index.java
@@ -98,6 +98,11 @@ public class Index extends AbstractIndex implements CachedWebDataSource {
}
File path = new File(exePath.getCanonicalFile() + File.separator + fileName);
path = new File(path.getCanonicalPath());
+ if (!path.exists()) {
+ if (!path.mkdirs()) {
+ throw new IOException("Unable to create NVD CVE Data directory");
+ }
+ }
return path;
}
diff --git a/src/main/java/org/codesecure/dependencycheck/data/nvdcve/xml/Importer.java b/src/main/java/org/codesecure/dependencycheck/data/nvdcve/xml/Importer.java
index f75bf4d3a..6eabad440 100644
--- a/src/main/java/org/codesecure/dependencycheck/data/nvdcve/xml/Importer.java
+++ b/src/main/java/org/codesecure/dependencycheck/data/nvdcve/xml/Importer.java
@@ -43,15 +43,17 @@ public class Importer {
*/
public static void importXML(File file) {
NvdCveParser indexer = null;
+ org.codesecure.dependencycheck.data.cpe.xml.Indexer cpeIndexer = null;
try {
-
indexer = new NvdCveParser();
-
indexer.openIndexWriter();
+ //HACK - hack to ensure all CPE data is stored in the index.
+ cpeIndexer = new org.codesecure.dependencycheck.data.cpe.xml.Indexer();
+ cpeIndexer.openIndexWriter();
+ indexer.setCPEIndexer(cpeIndexer);
indexer.parse(file);
-
} catch (CorruptIndexException ex) {
Logger.getLogger(Importer.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
@@ -60,6 +62,9 @@ public class Importer {
if (indexer != null) {
indexer.close();
}
+ if (cpeIndexer != null) {
+ cpeIndexer.close();
+ }
}
}
// public static void importXML(File file) throws FileNotFoundException, IOException, JAXBException,
diff --git a/src/main/java/org/codesecure/dependencycheck/data/nvdcve/xml/NvdCveParser.java b/src/main/java/org/codesecure/dependencycheck/data/nvdcve/xml/NvdCveParser.java
index ec11f3ff6..bf086beca 100644
--- a/src/main/java/org/codesecure/dependencycheck/data/nvdcve/xml/NvdCveParser.java
+++ b/src/main/java/org/codesecure/dependencycheck/data/nvdcve/xml/NvdCveParser.java
@@ -23,14 +23,17 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
+import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.FieldInfo.IndexOptions;
import org.apache.lucene.index.Term;
+import org.codesecure.dependencycheck.data.cpe.Entry;
import org.codesecure.dependencycheck.data.nvdcve.Fields;
import org.codesecure.dependencycheck.data.nvdcve.Index;
@@ -40,6 +43,19 @@ import org.codesecure.dependencycheck.data.nvdcve.Index;
*/
public class NvdCveParser extends Index {
+ //HACK - this has initially been placed here as a hack because not all
+ // of the CPEs listed in the NVD CVE are actually in the CPE xml file
+ // hosted by NIST.
+ private org.codesecure.dependencycheck.data.cpe.xml.Indexer cpeIndexer = null;
+
+ /**
+ * Adds the CPE Index to add additional CPEs found by parsing the NVD CVE.
+ * @param indexer the CPE Indexer to write new CPEs into.
+ */
+ public void setCPEIndexer(org.codesecure.dependencycheck.data.cpe.xml.Indexer indexer) {
+ this.cpeIndexer = indexer;
+ }
+
/**
* Parses an NVD CVE xml file using a buffered readerd. This
* method maybe more fragile then using a partial-unmarshalling SAX
@@ -164,10 +180,27 @@ public class NvdCveParser extends Index {
* Adds a CPE to the Lucene Document
* @param cpe a string representing a CPE
* @param doc a lucene document
+ * @throws CorruptIndexException is thrown if the CPE Index is corrupt
+ * @throws IOException is thrown if there is an IO Exception while writting to the CPE Index
*/
- private void addVulnerableCpe(String cpe, Document doc) {
+ private void addVulnerableCpe(String cpe, Document doc) throws CorruptIndexException, IOException {
Field vulnerable = new Field(Fields.VULNERABLE_CPE, cpe, Field.Store.NO, Field.Index.ANALYZED);
vulnerable.setIndexOptions(IndexOptions.DOCS_ONLY);
doc.add(vulnerable);
+
+ //HACK - this has initially been placed here as a hack because not all
+ // of the CPEs listed in the NVD CVE are actually in the CPE xml file
+ // hosted by NIST.
+ Entry cpeEntry = new Entry();
+ try {
+ cpeEntry.parseName(cpe);
+ cpeEntry.setNvdId("0");
+ cpeEntry.setTitle(cpe);
+ } catch (UnsupportedEncodingException ex) {
+ Logger.getLogger(NvdCveParser.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ if (cpeIndexer != null) {
+ cpeIndexer.saveEntry(cpeEntry);
+ }
}
}
diff --git a/src/main/java/org/codesecure/dependencycheck/dependency/EvidenceCollection.java b/src/main/java/org/codesecure/dependencycheck/dependency/EvidenceCollection.java
index 13650c495..f710d85b2 100644
--- a/src/main/java/org/codesecure/dependencycheck/dependency/EvidenceCollection.java
+++ b/src/main/java/org/codesecure/dependencycheck/dependency/EvidenceCollection.java
@@ -184,7 +184,7 @@ public class EvidenceCollection implements Iterable {
text = text.toLowerCase();
for (Evidence e : this.list) {
- if (e.used && e.value.contains(text)) {
+ if (e.used && e.value.toLowerCase().contains(text)) {
return true;
}
}
diff --git a/src/main/java/org/codesecure/dependencycheck/utils/CliParser.java b/src/main/java/org/codesecure/dependencycheck/utils/CliParser.java
index 6eedcb4be..4cb7c0b86 100644
--- a/src/main/java/org/codesecure/dependencycheck/utils/CliParser.java
+++ b/src/main/java/org/codesecure/dependencycheck/utils/CliParser.java
@@ -326,7 +326,7 @@ public final class CliParser {
* @return if auto-update is allowed.
*/
public boolean isAutoUpdate() {
- return (line != null) ? !line.hasOption(ArgumentName.DISABLE_AUTO_UPDATE) : false;
+ return (line != null) ? !line.hasOption(ArgumentName.DISABLE_AUTO_UPDATE) : true;
}
/**
diff --git a/src/main/resources/templates/HtmlReport.vsl b/src/main/resources/templates/HtmlReport.vsl
index 9316b6586..8723fbc03 100644
--- a/src/main/resources/templates/HtmlReport.vsl
+++ b/src/main/resources/templates/HtmlReport.vsl
@@ -34,7 +34,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.