diff --git a/pom.xml b/pom.xml index f32439732..3fbaadb3b 100644 --- a/pom.xml +++ b/pom.xml @@ -27,15 +27,24 @@ along with DependencyCheck. If not, see . jar DependencyCheck - http://maven.apache.org + http://codesecure.blogspot.com DependencyCheck is a simple utility that attempts to determine if there is a Common Product Enumeration (CPE) identifier for a given project dependency. If found, it will generate a report linking to the associated CVE entries. + + Jeremy Long + Jeremy Long jeremy.long@gmail.com + Codesecure + http://codesecure.blogspot.com + + architect + developer + - + scm:git:git@github.com:jeremylong/DependencyCheck.git https://github.com/jeremylong/DependencyCheck.git scm:git:git@github.com:jeremylong/DependencyCheck.git @@ -48,7 +57,7 @@ along with DependencyCheck. If not, see . UTF-8 - + @@ -68,7 +77,7 @@ along with DependencyCheck. If not, see . false - + org.apache.maven.plugins @@ -155,7 +164,7 @@ along with DependencyCheck. If not, see . 0 0 - + org.codesecure.dependencycheck.utils.SSDeep 0 @@ -164,7 +173,7 @@ along with DependencyCheck. If not, see . - + diff --git a/src/main/java/org/codesecure/dependencycheck/scanner/JarAnalyzer.java b/src/main/java/org/codesecure/dependencycheck/scanner/JarAnalyzer.java index 10b4d20eb..0588a1f6a 100644 --- a/src/main/java/org/codesecure/dependencycheck/scanner/JarAnalyzer.java +++ b/src/main/java/org/codesecure/dependencycheck/scanner/JarAnalyzer.java @@ -23,6 +23,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.util.HashMap; +import java.util.Map.Entry; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; @@ -46,21 +47,44 @@ import org.codesecure.dependencycheck.utils.Checksum; */ public class JarAnalyzer implements Analyzer { + /** + * item in some manifest, should be considered medium confidence. + */ private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2 + /** + * item in some manifest, should be considered medium confidence. + */ private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2 + /** + * item in some manifest, should be considered medium confidence. + */ private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core + /** + * item in some manifest, should be considered medium confidence. + */ private static final String BUNDLE_VENDOR = "Bundle-Vendor"; //: Apache Software Foundation + /** + * An enumeration to keep track of the characters in a string as it is being + * read in one character at a time. + */ private enum STRING_STATE { - ALPHA, NUMBER, + PERIOD, OTHER } + /** + * Determines type of the character passed in. + * @param c a character + * @return a STRING_STATE representing whether the character is number, alpha, or other. + */ private STRING_STATE determineState(char c) { - if (c >= '0' && c <= '9' || c == '.') { + if (c >= '0' && c <= '9') { return STRING_STATE.NUMBER; + } else if (c == '.') { + return STRING_STATE.PERIOD; } else if (c >= 'a' && c <= 'z') { return STRING_STATE.ALPHA; } else { @@ -83,8 +107,11 @@ public class JarAnalyzer implements Analyzer { String fileName = file.getName(); dependency.setFileName(fileName); dependency.setFilePath(file.getCanonicalPath()); - String fileNameEvidence = fileName.substring(0, fileName.length() - 4) - .toLowerCase().replace('-', ' ').replace('_', ' '); + + //slightly process the filename to chunk it into distinct words, numbers. + // Yes, the lucene analyzer might do this, but I want a little better control + // over the process. + String fileNameEvidence = fileName.substring(0, fileName.length() - 4).toLowerCase().replace('-', ' ').replace('_', ' '); StringBuilder sb = new StringBuilder(fileNameEvidence.length()); STRING_STATE state = determineState(fileNameEvidence.charAt(0)); @@ -92,9 +119,14 @@ public class JarAnalyzer implements Analyzer { char c = fileNameEvidence.charAt(i); STRING_STATE newState = determineState(c); if (newState != state) { - sb.append(' '); - state = newState; + if ((state != STRING_STATE.NUMBER && newState == STRING_STATE.PERIOD) + || (state == STRING_STATE.PERIOD && newState != STRING_STATE.NUMBER) + || (state == STRING_STATE.ALPHA || newState == STRING_STATE.ALPHA) + || ((state == STRING_STATE.OTHER || newState == STRING_STATE.OTHER) && c != ' ')) { + sb.append(' '); + } } + state = newState; sb.append(c); } Pattern rx = Pattern.compile("\\s\\s+"); @@ -307,58 +339,48 @@ public class JarAnalyzer implements Analyzer { EvidenceCollection versionEvidence = dependency.getVendorEvidence(); String source = "Manifest"; - String name = Attributes.Name.IMPLEMENTATION_TITLE.toString(); - String value = atts.getValue(Attributes.Name.IMPLEMENTATION_TITLE); - if (value != null) { - titleEvidence.addEvidence(source, name, value, Evidence.Confidence.HIGH); - } - name = Attributes.Name.IMPLEMENTATION_VERSION.toString(); - value = atts.getValue(Attributes.Name.IMPLEMENTATION_VERSION); - if (value != null) { - versionEvidence.addEvidence(source, name, value, Evidence.Confidence.HIGH); - } - - name = Attributes.Name.IMPLEMENTATION_VENDOR.toString(); - value = atts.getValue(Attributes.Name.IMPLEMENTATION_VENDOR); - if (value != null) { - vendorEvidence.addEvidence(source, name, value, Evidence.Confidence.HIGH); - } - - name = Attributes.Name.IMPLEMENTATION_VENDOR_ID.toString(); - value = atts.getValue(Attributes.Name.IMPLEMENTATION_VENDOR_ID); - if (value != null) { - vendorEvidence.addEvidence(source, name, value, Evidence.Confidence.MEDIUM); - } - - name = BUNDLE_DESCRIPTION; - value = atts.getValue(BUNDLE_DESCRIPTION); - if (value != null) { - titleEvidence.addEvidence(source, name, value, Evidence.Confidence.MEDIUM); - } - - name = BUNDLE_VENDOR; - value = atts.getValue(BUNDLE_VENDOR); - if (value != null) { - vendorEvidence.addEvidence(source, name, value, Evidence.Confidence.MEDIUM); - } - - name = BUNDLE_VERSION; - value = atts.getValue(BUNDLE_VERSION); - if (value != null) { - versionEvidence.addEvidence(source, name, value, Evidence.Confidence.MEDIUM); - } - name = BUNDLE_NAME; - value = atts.getValue(BUNDLE_NAME); - if (value != null) { - titleEvidence.addEvidence(source, name, value, Evidence.Confidence.LOW); - } - - name = Attributes.Name.MAIN_CLASS.toString(); - value = atts.getValue(Attributes.Name.MAIN_CLASS); - if (value != null) { - titleEvidence.addEvidence(source, name, value, Evidence.Confidence.MEDIUM); - vendorEvidence.addEvidence(source, name, value, Evidence.Confidence.MEDIUM); + for (Entry entry : atts.entrySet()) { + String key = entry.getKey().toString(); + String value = atts.getValue(key); + if (key.equals(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { + titleEvidence.addEvidence(source, key, value, Evidence.Confidence.HIGH); + } else if (key.equals(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { + versionEvidence.addEvidence(source, key, value, Evidence.Confidence.HIGH); + } else if (key.equals(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { + vendorEvidence.addEvidence(source, key, value, Evidence.Confidence.HIGH); + } else if (key.equals(Attributes.Name.IMPLEMENTATION_VENDOR_ID.toString())) { + vendorEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM); + } else if (key.equals(BUNDLE_DESCRIPTION)) { + titleEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM); + } else if (key.equals(BUNDLE_NAME)) { + titleEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM); + } else if (key.equals(BUNDLE_VENDOR)) { + vendorEvidence.addEvidence(source, key, value, Evidence.Confidence.HIGH); + } else if (key.equals(BUNDLE_VERSION)) { + versionEvidence.addEvidence(source, key, value, Evidence.Confidence.HIGH); + } else if (key.equals(Attributes.Name.MAIN_CLASS.toString())) { + titleEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM); + vendorEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM); + } else { + key = key.toLowerCase(); + if (key.contains("version")) { + versionEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM); + } else if (key.contains("title")) { + titleEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM); + } else if (key.contains("vendor")) { + vendorEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM); + } else if (key.contains("name")) { + titleEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM); + vendorEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM); + } else { + titleEvidence.addEvidence(source, key, value, Evidence.Confidence.LOW); + vendorEvidence.addEvidence(source, key, value, Evidence.Confidence.LOW); + if (value.matches(".*\\d.*")) { + versionEvidence.addEvidence(source, key, value, Evidence.Confidence.LOW); + } + } + } } } }