mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-03-24 18:11:47 +01:00
fixed JarAnalyzer so it grabs more data from the JAR.
This commit is contained in:
11
pom.xml
11
pom.xml
@@ -27,12 +27,21 @@ along with DependencyCheck. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>DependencyCheck</name>
|
<name>DependencyCheck</name>
|
||||||
<url>http://maven.apache.org</url>
|
<url>http://codesecure.blogspot.com</url>
|
||||||
<description>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.</description>
|
<description>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.</description>
|
||||||
|
<organization>
|
||||||
|
<name>Jeremy Long</name>
|
||||||
|
</organization>
|
||||||
<developers>
|
<developers>
|
||||||
<developer>
|
<developer>
|
||||||
<name>Jeremy Long</name>
|
<name>Jeremy Long</name>
|
||||||
<email>jeremy.long@gmail.com</email>
|
<email>jeremy.long@gmail.com</email>
|
||||||
|
<organization>Codesecure</organization>
|
||||||
|
<organizationUrl>http://codesecure.blogspot.com</organizationUrl>
|
||||||
|
<roles>
|
||||||
|
<role>architect</role>
|
||||||
|
<role>developer</role>
|
||||||
|
</roles>
|
||||||
</developer>
|
</developer>
|
||||||
</developers>
|
</developers>
|
||||||
<scm>
|
<scm>
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.jar.Attributes;
|
import java.util.jar.Attributes;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import java.util.jar.Manifest;
|
import java.util.jar.Manifest;
|
||||||
@@ -46,21 +47,44 @@ import org.codesecure.dependencycheck.utils.Checksum;
|
|||||||
*/
|
*/
|
||||||
public class JarAnalyzer implements Analyzer {
|
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
|
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
|
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
|
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
|
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 {
|
private enum STRING_STATE {
|
||||||
|
|
||||||
ALPHA,
|
ALPHA,
|
||||||
NUMBER,
|
NUMBER,
|
||||||
|
PERIOD,
|
||||||
OTHER
|
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) {
|
private STRING_STATE determineState(char c) {
|
||||||
if (c >= '0' && c <= '9' || c == '.') {
|
if (c >= '0' && c <= '9') {
|
||||||
return STRING_STATE.NUMBER;
|
return STRING_STATE.NUMBER;
|
||||||
|
} else if (c == '.') {
|
||||||
|
return STRING_STATE.PERIOD;
|
||||||
} else if (c >= 'a' && c <= 'z') {
|
} else if (c >= 'a' && c <= 'z') {
|
||||||
return STRING_STATE.ALPHA;
|
return STRING_STATE.ALPHA;
|
||||||
} else {
|
} else {
|
||||||
@@ -83,8 +107,11 @@ public class JarAnalyzer implements Analyzer {
|
|||||||
String fileName = file.getName();
|
String fileName = file.getName();
|
||||||
dependency.setFileName(fileName);
|
dependency.setFileName(fileName);
|
||||||
dependency.setFilePath(file.getCanonicalPath());
|
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());
|
StringBuilder sb = new StringBuilder(fileNameEvidence.length());
|
||||||
STRING_STATE state = determineState(fileNameEvidence.charAt(0));
|
STRING_STATE state = determineState(fileNameEvidence.charAt(0));
|
||||||
|
|
||||||
@@ -92,9 +119,14 @@ public class JarAnalyzer implements Analyzer {
|
|||||||
char c = fileNameEvidence.charAt(i);
|
char c = fileNameEvidence.charAt(i);
|
||||||
STRING_STATE newState = determineState(c);
|
STRING_STATE newState = determineState(c);
|
||||||
if (newState != state) {
|
if (newState != state) {
|
||||||
sb.append(' ');
|
if ((state != STRING_STATE.NUMBER && newState == STRING_STATE.PERIOD)
|
||||||
state = newState;
|
|| (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);
|
sb.append(c);
|
||||||
}
|
}
|
||||||
Pattern rx = Pattern.compile("\\s\\s+");
|
Pattern rx = Pattern.compile("\\s\\s+");
|
||||||
@@ -307,58 +339,48 @@ public class JarAnalyzer implements Analyzer {
|
|||||||
EvidenceCollection versionEvidence = dependency.getVendorEvidence();
|
EvidenceCollection versionEvidence = dependency.getVendorEvidence();
|
||||||
|
|
||||||
String source = "Manifest";
|
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();
|
for (Entry<Object, Object> entry : atts.entrySet()) {
|
||||||
value = atts.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
|
String key = entry.getKey().toString();
|
||||||
if (value != null) {
|
String value = atts.getValue(key);
|
||||||
versionEvidence.addEvidence(source, name, value, Evidence.Confidence.HIGH);
|
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())) {
|
||||||
name = Attributes.Name.IMPLEMENTATION_VENDOR.toString();
|
versionEvidence.addEvidence(source, key, value, Evidence.Confidence.HIGH);
|
||||||
value = atts.getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
|
} else if (key.equals(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) {
|
||||||
if (value != null) {
|
vendorEvidence.addEvidence(source, key, value, Evidence.Confidence.HIGH);
|
||||||
vendorEvidence.addEvidence(source, name, 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)) {
|
||||||
name = Attributes.Name.IMPLEMENTATION_VENDOR_ID.toString();
|
titleEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM);
|
||||||
value = atts.getValue(Attributes.Name.IMPLEMENTATION_VENDOR_ID);
|
} else if (key.equals(BUNDLE_NAME)) {
|
||||||
if (value != null) {
|
titleEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM);
|
||||||
vendorEvidence.addEvidence(source, name, value, Evidence.Confidence.MEDIUM);
|
} else if (key.equals(BUNDLE_VENDOR)) {
|
||||||
}
|
vendorEvidence.addEvidence(source, key, value, Evidence.Confidence.HIGH);
|
||||||
|
} else if (key.equals(BUNDLE_VERSION)) {
|
||||||
name = BUNDLE_DESCRIPTION;
|
versionEvidence.addEvidence(source, key, value, Evidence.Confidence.HIGH);
|
||||||
value = atts.getValue(BUNDLE_DESCRIPTION);
|
} else if (key.equals(Attributes.Name.MAIN_CLASS.toString())) {
|
||||||
if (value != null) {
|
titleEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM);
|
||||||
titleEvidence.addEvidence(source, name, value, Evidence.Confidence.MEDIUM);
|
vendorEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM);
|
||||||
}
|
} else {
|
||||||
|
key = key.toLowerCase();
|
||||||
name = BUNDLE_VENDOR;
|
if (key.contains("version")) {
|
||||||
value = atts.getValue(BUNDLE_VENDOR);
|
versionEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM);
|
||||||
if (value != null) {
|
} else if (key.contains("title")) {
|
||||||
vendorEvidence.addEvidence(source, name, value, Evidence.Confidence.MEDIUM);
|
titleEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM);
|
||||||
}
|
} else if (key.contains("vendor")) {
|
||||||
|
vendorEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM);
|
||||||
name = BUNDLE_VERSION;
|
} else if (key.contains("name")) {
|
||||||
value = atts.getValue(BUNDLE_VERSION);
|
titleEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM);
|
||||||
if (value != null) {
|
vendorEvidence.addEvidence(source, key, value, Evidence.Confidence.MEDIUM);
|
||||||
versionEvidence.addEvidence(source, name, value, Evidence.Confidence.MEDIUM);
|
} else {
|
||||||
}
|
titleEvidence.addEvidence(source, key, value, Evidence.Confidence.LOW);
|
||||||
name = BUNDLE_NAME;
|
vendorEvidence.addEvidence(source, key, value, Evidence.Confidence.LOW);
|
||||||
value = atts.getValue(BUNDLE_NAME);
|
if (value.matches(".*\\d.*")) {
|
||||||
if (value != null) {
|
versionEvidence.addEvidence(source, key, value, Evidence.Confidence.LOW);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user