diff --git a/analyzers/archive-analyzer.html b/analyzers/archive-analyzer.html index 574e18864..63c604000 100644 --- a/analyzers/archive-analyzer.html +++ b/analyzers/archive-analyzer.html @@ -1,13 +1,13 @@
@Override
public void trace(String msg) {
if (task != null) {
task.log(msg, Project.MSG_VERBOSE);
}
public void debug(String msg) {
task.log(msg, Project.MSG_DEBUG);
Note: failures are anticipated and checked for with assertions while errors are unanticipated.
Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.
[Summary] [Package List] [Test Cases]
OWASP dependency-check-cli is an command line tool that uses dependency-check-core to detect publicly disclosed vulnerabilities associated with the scanned project dependencies. The tool will generate a report listing the dependency, any identified Common Platform Enumeration (CPE) identifiers, and the associated Common Vulnerability and Exposure (CVE) entries.
Download the dependency-check command line tool here. Extract the zip file to a location on your computer and put the ‘bin’ directory into the path environment variable. On *nix systems you will likely need to make the shell script executable:
$ chmod +777 dependency-check.sh diff --git a/dependency-check-cli/integration.html b/dependency-check-cli/integration.html index 480a38331..3a5c2d579 100644 --- a/dependency-check-cli/integration.html +++ b/dependency-check-cli/integration.html @@ -1,13 +1,13 @@ - + dependency-check-cli – Continuous Integration @@ -54,7 +54,7 @@
boolean identifierAdded = false;
for (IndexEntry e : entries) {
LOGGER.debug("Verifying entry: {}", e);
if (verifyEntry(e, dependency)) {
final String vendor = e.getVendor();
final String product = e.getProduct();
LOGGER.debug("identified vendor/product: {}/{}", vendor, product);
identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence);
if (identifierAdded) {
break;
final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS);
for (ScoreDoc d : docs.scoreDocs) {
if (d.score >= 0.08) {
final Document doc = cpe.getDocument(d.doc);
final IndexEntry entry = new IndexEntry();
entry.setVendor(doc.get(Fields.VENDOR));
entry.setProduct(doc.get(Fields.PRODUCT));
entry.setSearchScore(d.score);
if (!ret.contains(entry)) {
ret.add(entry);
*/
private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) {
boolean isValid = false;
//TODO - does this nullify some of the fuzzy matching that happens in the lucene search?
// for instance CPE some-component and in the evidence we have SomeComponent.
if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct())
&& collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) {
//&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion())
isValid = true;
return isValid;
private boolean collectionContainsString(EvidenceCollection ec, String text) {
//TODO - likely need to change the split... not sure if this will work for CPE with special chars
if (text == null) {
return false;
final String[] words = text.split("[\\s_-]");
final List<String> list = new ArrayList<String>();
String tempWord = null;
for (String word : words) {
/*
so { "m", "core", "sample" } -> { "mcore", "sample" }
if (tempWord != null) {
list.add(tempWord + word);
tempWord = null;
} else if (word.length() <= 2) {
tempWord = word;
} else {
list.add(word);
if (!list.isEmpty()) {
final String tmp = list.get(list.size() - 1) + tempWord;
list.add(tmp);
if (list.isEmpty()) {
boolean contains = true;
for (String word : list) {
contains &= ec.containsUsedString(word);
return contains;
protected boolean determineIdentifiers(Dependency dependency, String vendor, String product,
Confidence currentConfidence) throws UnsupportedEncodingException {
final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product);
DependencyVersion bestGuess = new DependencyVersion("-");
Confidence bestGuessConf = null;
boolean hasBroadMatch = false;
final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>();
for (Confidence conf : Confidence.values()) {
// if (conf.compareTo(currentConfidence) > 0) {
// break;
// }
for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) {
final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue());
if (evVer == null) {
continue;
for (VulnerableSoftware vs : cpes) {
DependencyVersion dbVer;
if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) {
dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + '.' + vs.getUpdate());
dbVer = DependencyVersionUtil.parseVersion(vs.getVersion());
if (dbVer == null) { //special case, no version specified - everything is vulnerable
hasBroadMatch = true;
final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf);
//TODO the following isn't quite right is it? need to think about this guessing game a bit more.
if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size()
&& evVer.matchesAtLeastThreeLevels(dbVer)) {
if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) {
bestGuess = evVer;
bestGuessConf = conf;
final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString());
String url = null;
if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess.
final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product);
url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8"));
if (bestGuessConf == null) {
bestGuessConf = Confidence.LOW;
final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf);
collected.add(match);
Collections.sort(collected);
final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence();
final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence();
for (IdentifierMatch m : collected) {
if (bestIdentifierQuality.equals(m.getConfidence())
&& bestEvidenceQuality.equals(m.getEvidenceConfidence())) {
final Identifier i = m.getIdentifier();
if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) {
i.setConfidence(Confidence.LOW);
i.setConfidence(bestEvidenceQuality);
dependency.addIdentifier(i);
identifierAdded = true;
return identifierAdded;
* @param evidenceConfidence the confidence of the evidence used to find the identifier
IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) {
this.identifier = new Identifier(type, value, url);
this.confidence = identifierConfidence;
this.evidenceConfidence = evidenceConfidence;
//<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier">
public Confidence getEvidenceConfidence() {
return evidenceConfidence;
public IdentifierConfidence getConfidence() {
return confidence;
public Identifier getIdentifier() {
return identifier;
for (Identifier i : dependency2.getIdentifiers()) {
if ("cpe".equals(i.getType())) {
cpeCount2 += 1;
if (cpeCount1 > 0 && cpeCount1 == cpeCount2) {
for (Identifier i : dependency1.getIdentifiers()) {
private void removeBadSpringMatches(Dependency dependency) {
String mustContain = null;
for (Identifier i : dependency.getIdentifiers()) {
if ("maven".contains(i.getType())) {
if (i.getValue() != null && i.getValue().startsWith("org.springframework.")) {
final int endPoint = i.getValue().indexOf(':', 19);
if (endPoint >= 0) {
if (mustContain != null) {
final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
while (itr.hasNext()) {
final List<Identifier> ids = new ArrayList<Identifier>(dependency.getIdentifiers());
Collections.sort(ids);
final ListIterator<Identifier> mainItr = ids.listIterator();
while (mainItr.hasNext()) {
final Identifier currentId = mainItr.next();
final VulnerableSoftware currentCpe = parseCpe(currentId.getType(), currentId.getValue());
if (currentCpe == null) {
final ListIterator<Identifier> subItr = ids.listIterator(mainItr.nextIndex());
while (subItr.hasNext()) {
final Identifier nextId = subItr.next();
final VulnerableSoftware nextCpe = parseCpe(nextId.getType(), nextId.getValue());
if (nextCpe == null) {
//TODO fix the version problem below
if (currentCpe.getVendor().equals(nextCpe.getVendor())) {
if (currentCpe.getProduct().equals(nextCpe.getProduct())) {
// see if one is contained in the other.. remove the contained one from dependency.getIdentifier
/**
private void removeJreEntries(Dependency dependency) {
final Set<Identifier> identifiers = dependency.getIdentifiers();
final Iterator<Identifier> itr = identifiers.iterator();
final Identifier i = itr.next();
final Matcher coreCPE = CORE_JAVA.matcher(i.getValue());
final Matcher coreFiles = CORE_FILES.matcher(dependency.getFileName());
if (coreCPE.matches() && !coreFiles.matches()) {
itr.remove();
final Matcher coreJsfCPE = CORE_JAVA_JSF.matcher(i.getValue());
final Matcher coreJsfFiles = CORE_JSF_FILES.matcher(dependency.getFileName());
if (coreJsfCPE.matches() && !coreJsfFiles.matches()) {
private VulnerableSoftware parseCpe(String type, String value) {
if (!"cpe".equals(type)) {
return null;
final VulnerableSoftware cpe = new VulnerableSoftware();
try {
cpe.parseName(value);
} catch (UnsupportedEncodingException ex) {
LOGGER.trace("", ex);
return cpe;
//Set<Evidence> groupId = dependency.getVendorEvidence().getEvidence("pom", "groupid");
//Set<Evidence> artifactId = dependency.getVendorEvidence().getEvidence("pom", "artifactid");
//TODO move this startsWith expression to the base suppression file
if ((i.getValue().matches(".*c\\+\\+.*")
|| i.getValue().startsWith("cpe:/a:file:file")
|| dependency.getFileName().toLowerCase().endsWith(".war"))) {
} else if ((i.getValue().startsWith("cpe:/a:jquery:jquery")
|| i.getValue().startsWith("cpe:/a:prototypejs:prototype")
|| dependency.getFileName().toLowerCase().endsWith(".exe"))) {
} else if ((i.getValue().startsWith("cpe:/a:microsoft:excel")
|| i.getValue().startsWith("cpe:/a:microsoft:word")
|| dependency.getFileName().toLowerCase().endsWith("pom.xml"))) {
} else if (i.getValue().startsWith("cpe:/a:apache:maven")
&& !dependency.getFileName().toLowerCase().matches("maven-core-[\\d\\.]+\\.jar")) {
} else if (i.getValue().startsWith("cpe:/a:m-core:m-core")
&& !dependency.getEvidenceUsed().containsUsedString("m-core")) {
} else if (i.getValue().startsWith("cpe:/a:jboss:jboss")
&& !dependency.getFileName().toLowerCase().matches("jboss-?[\\d\\.-]+(GA)?\\.jar")) {
//TODO move this to the hint analyzer
for (final Identifier identifier : dependency.getIdentifiers()) {
if ("cpe".equals(identifier.getType()) && identifier.getValue() != null
&& (identifier.getValue().startsWith("cpe:/a:oracle:opensso:")
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
for (Identifier id : dependency.getIdentifiers()) {
if ("cpe".equals(id.getType())) {
final String value = id.getValue();
final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
dependency.getVulnerabilities().addAll(vulns);
} catch (DatabaseException ex) {
throw new AnalysisException(ex);
for (Identifier id : dependency.getSuppressedIdentifiers()) {
final Set<Pair<String, String>> data = cve.getVendorProductList();
for (Pair<String, String> pair : data) {
v.setStringValue(pair.getLeft());
p.setStringValue(pair.getRight());
indexWriter.addDocument(doc);
LOGGER.debug("", ex);
throw new IndexException("Error reading CPE data", ex);
public Document getDocument(int documentId) throws IOException {
return indexSearcher.doc(documentId);
* @author Jeremy Long
public class IndexEntry implements Serializable {
public String getVendor() {
return vendor;
public void setVendor(String vendor) {
this.vendor = vendor;
public String getProduct() {
return product;
public void setProduct(String product) {
this.product = product;
public void setSearchScore(float searchScore) {
this.searchScore = searchScore;
public boolean equals(Object obj) {
if (obj == null) {
if (getClass() != obj.getClass()) {
final IndexEntry other = (IndexEntry) obj;
if ((this.vendor == null) ? (other.vendor != null) : !this.vendor.equals(other.vendor)) {
if ((this.product == null) ? (other.product != null) : !this.product.equals(other.product)) {
* The char term attribute.
private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
protected CharTermAttribute getTermAtt() {
return termAtt;
protected LinkedList<String> getTokens() {
return tokens;
public AbstractTokenizingFilter(TokenStream stream) {
super(stream);
tokens = new LinkedList<String>();
protected boolean addTerm() {
final boolean termAdded = !tokens.isEmpty();
if (termAdded) {
final String term = tokens.pop();
clearAttributes();
termAtt.append(term);
return termAdded;
protected boolean isTokenChar(int c) {
return Character.isLetter(c) || Character.isDigit(c);
public UrlTokenizingFilter(TokenStream stream) {
public boolean incrementToken() throws IOException {
final LinkedList<String> tokens = getTokens();
final CharTermAttribute termAtt = getTermAtt();
if (tokens.isEmpty() && input.incrementToken()) {
final String text = new String(termAtt.buffer(), 0, termAtt.length());
if (UrlStringUtils.containsUrl(text)) {
final String[] parts = text.split("\\s");
for (String part : parts) {
if (UrlStringUtils.isUrl(part)) {
tokens.add(text);
return addTerm();
// vim: cc=120:sw=4:ts=4:sts=4
protected Connection getConnection() {
return conn;
public void close() {
if (conn != null) {
conn.close();
conn = null;
@SuppressWarnings("FinalizeDeclaration")
protected void finalize() throws Throwable {
LOGGER.debug("Entering finalize");
close();
super.finalize();
public Set<VulnerableSoftware> getCPEs(String vendor, String product) {
final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>();
ResultSet rs = null;
PreparedStatement ps = null;
ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES"));
ps.setString(1, vendor);
ps.setString(2, product);
rs = ps.executeQuery();
while (rs.next()) {
final VulnerableSoftware vs = new VulnerableSoftware();
vs.setCpe(rs.getString(1));
cpe.add(vs);
} catch (SQLException ex) {
LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
} finally {
DBUtils.closeResultSet(rs);
DBUtils.closeStatement(ps);
ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST"));
data.add(new Pair<String, String>(rs.getString(1), rs.getString(2)));
ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES"));
prop.setProperty(rs.getString(1), rs.getString(2));
public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException {
cpe.parseName(cpeStr);
final DependencyVersion detectedVersion = parseDependencyVersion(cpe);
final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>();
ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE"));
ps.setString(1, cpe.getVendor());
ps.setString(2, cpe.getProduct());
String currentCVE = "";
final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>();
final String cveId = rs.getString(1);
if (!currentCVE.equals(cveId)) { //check for match and add
final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion);
if (matchedCPE != null) {
final Vulnerability v = getVulnerability(currentCVE);
v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null);
vulnerabilities.add(v);
vulnSoftware.clear();
currentCVE = cveId;
final String cpeId = rs.getString(2);
final String previous = rs.getString(3);
final Boolean p = previous != null && !previous.isEmpty();
vulnSoftware.put(cpeId, p);
//remember to process the last set of CVE/CPE entries
throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex);
return vulnerabilities;
DependencyVersion identifiedVersion) {
final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product);
final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>();
final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString());
String majorVersionMatch = null;
for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
final DependencyVersion v = parseDependencyVersion(entry.getKey());
if (v == null || "-".equals(v.toString())) { //all versions
return entry;
if (entry.getValue()) {
if (matchesAnyPrevious) {
majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0));
final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1;
//yes, we are iterating over this twice. The first time we are skipping versions those that affect all versions
//then later we process those that affect all versions. This could be done with sorting...
if (!entry.getValue()) {
//this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this.
if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
//this can't dereference a null 'identifiedVersion' because if it was null we would have exited
//in the above loop or just after loop (if matchesAnyPrevious return null).
if (identifiedVersion.equals(v)) {
private DependencyVersion parseDependencyVersion(String cpeStr) {
//never going to happen.
return parseDependencyVersion(cpe);
private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) {
final DependencyVersion cpeVersion;
if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) {
final String versionText;
if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) {
versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate());
versionText = cpe.getVersion();
cpeVersion = DependencyVersionUtil.parseVersion(versionText);
cpeVersion = new DependencyVersion("-");
return cpeVersion;
int len;
while ((len = cin.read(buffer)) > 0) {
out.write(buffer, 0, len);
public enum Confidence {
public String getFileName() {
return this.fileName;
public void addIdentifier(Identifier identifier) {
this.identifiers.add(identifier);
public EvidenceCollection getVendorEvidence() {
return this.vendorEvidence;
public EvidenceCollection getProductEvidence() {
return this.productEvidence;
public EvidenceCollection getVersionEvidence() {
return this.versionEvidence;
public SortedSet<Vulnerability> getVulnerabilities() {
public String getValue() {
used = true;
return value;
public boolean isUsed() {
return used;
public Confidence getConfidence() {
* Used to iterate over highest confidence evidence contained in the collection.
private static final Filter<Evidence> HIGHEST_CONFIDENCE = new Filter<Evidence>() {
public boolean passes(Evidence evidence) {
return evidence.getConfidence() == Confidence.HIGHEST;
* Used to iterate over high confidence evidence contained in the collection.
private static final Filter<Evidence> HIGH_CONFIDENCE = new Filter<Evidence>() {
return evidence.getConfidence() == Confidence.HIGH;
return evidence.getConfidence() == Confidence.MEDIUM;
return evidence.getConfidence() == Confidence.LOW;
return evidence.isUsed();
public final Iterable<Evidence> iterator(Confidence confidence) {
if (confidence == Confidence.HIGHEST) {
return EvidenceCollection.HIGHEST_CONFIDENCE.filter(this.list);
} else if (confidence == Confidence.HIGH) {
return EvidenceCollection.HIGH_CONFIDENCE.filter(this.list);
} else if (confidence == Confidence.MEDIUM) {
return EvidenceCollection.MEDIUM_CONFIDENCE.filter(this.list);
return EvidenceCollection.LOW_CONFIDENCE.filter(this.list);
public Iterator<Evidence> iterator() {
return list.iterator();
public boolean containsUsedString(String text) {
final String textToTest = text.toLowerCase();
for (Evidence e : EvidenceCollection.EVIDENCE_USED.filter(this)) {
//TODO consider changing the regex to only compare alpha-numeric (i.e. strip everything else)
final String value = urlCorrection(e.getValue().toLowerCase()).replaceAll("[\\s_-]", "");
if (value.contains(textToTest)) {
return true;
private String urlCorrection(String value) {
if (value == null || !UrlStringUtils.containsUrl(value)) {
final StringBuilder sb = new StringBuilder(value.length());
final String[] parts = value.split("\\s");
final List<String> data = UrlStringUtils.extractImportantUrlData(part);
sb.append(' ').append(StringUtils.join(data, ' '));
} catch (MalformedURLException ex) {
LOGGER.debug("error parsing {}", part, ex);
sb.append(' ').append(part);
return sb.toString().trim();
public class Identifier implements Serializable, Comparable<Identifier> {
* @param url the identifier url.
public Identifier(String type, String value, String url) {
this.type = type;
this.value = value;
this.url = url;
public void setConfidence(Confidence confidence) {
this.confidence = confidence;
public String getType() {
return type;
public int hashCode() {
int hash = 5;
hash = 53 * hash + (this.value != null ? this.value.hashCode() : 0);
hash = 53 * hash + (this.type != null ? this.type.hashCode() : 0);
return hash;
public int compareTo(Identifier o) {
if (o == null) {
return -1;
return this.value.compareTo(o.value);
public class Reference implements Serializable, Comparable<Reference> {
public int compareTo(Reference o) {
if (source.equals(o.source)) {
if (name.equals(o.name)) {
if (url.equals(o.url)) {
return 0; //they are equal
return name.compareTo(o.name);
return source.compareTo(o.source);
public class VulnerableSoftware extends IndexEntry implements Serializable, Comparable<VulnerableSoftware> {
public void setCpe(String cpe) {
parseName(cpe);
LOGGER.warn("Character encoding is unsupported for CPE '{}'.", cpe);
setName(cpe);
public void parseName(String cpeName) throws UnsupportedEncodingException {
this.name = cpeName;
if (cpeName != null && cpeName.length() > 7) {
final String[] data = cpeName.substring(7).split(":");
if (data.length >= 1) {
this.setVendor(urlDecode(data[0]));
if (data.length >= 2) {
this.setProduct(urlDecode(data[1]));
if (data.length >= 3) {
version = urlDecode(data[2]);
if (data.length >= 4) {
update = urlDecode(data[3]);
if (data.length >= 5) {
edition = urlDecode(data[4]);
int hash = 7;
hash = 83 * hash + (this.getName() != null ? this.getName().hashCode() : 0);
public String getName() {
return name;
public String getVersion() {
return version;
public String getUpdate() {
return update;
private String urlDecode(String string) {
final String text = string.replace("+", "%2B");
String result;
result = URLDecoder.decode(text, "UTF-8");
} catch (UnsupportedEncodingException ex1) {
result = defaultUrlDecode(text);
return result;
public boolean isRegex() {
return regex;
public boolean isCaseSensitive() {
return caseSensitive;
public boolean matches(String text) {
if (this.regex) {
Pattern rx;
if (this.caseSensitive) {
return rx.matcher(text).matches();
return value.equals(text);
return value.equalsIgnoreCase(text);
if (gav != null) {
boolean gavFound = false;
if (identifierMatches("maven", this.gav, i)) {
gavFound = true;
if (!gavFound) {
return;
if (this.hasCpe()) {
for (PropertyType c : this.cpe) {
if (identifierMatches("cpe", c, i)) {
if (!isBase()) {
dependency.addSuppressedIdentifier(i);
if (hasCve() || hasCwe() || hasCvssBelow()) {
boolean cpeHasNoVersion(PropertyType c) {
return !c.isRegex() && StringUtils.countMatches(c.getValue(), ':') == 3;
boolean identifierMatches(String identifierType, PropertyType suppressionEntry, Identifier identifier) {
if (identifierType.equals(identifier.getType())) {
if (suppressionEntry.matches(identifier.getValue())) {
} else if ("cpe".equals(identifierType) && cpeHasNoVersion(suppressionEntry)) {
if (suppressionEntry.isCaseSensitive()) {
return identifier.getValue().startsWith(suppressionEntry.getValue());
final String id = identifier.getValue().toLowerCase();
final String check = suppressionEntry.getValue().toLowerCase();
return id.startsWith(check);
public static void closeStatement(Statement statement) {
if (statement != null) {
statement.close();
LOGGER.trace(statement.toString(), ex);
public static void closeResultSet(ResultSet rs) {
if (rs != null) {
rs.close();
LOGGER.trace(rs.toString(), ex);
* @param version the well formatted version number to parse
public DependencyVersion(String version) {
parseVersion(version);
public final void parseVersion(String version) {
versionParts = new ArrayList<String>();
if (version != null) {
final Pattern rx = Pattern.compile("(\\d+[a-z]{1,3}$|[a-z]+\\d+|\\d+|(release|beta|alpha)$)");
final Matcher matcher = rx.matcher(version.toLowerCase());
while (matcher.find()) {
versionParts.add(matcher.group());
if (versionParts.isEmpty()) {
versionParts.add(version);
public List<String> getVersionParts() {
return versionParts;
public String toString() {
return StringUtils.join(versionParts, '.');
final DependencyVersion other = (DependencyVersion) obj;
final int max = (this.versionParts.size() < other.versionParts.size())
? this.versionParts.size() : other.versionParts.size();
//TODO steal better version of code from compareTo
for (int i = 0; i < max; i++) {
final String thisPart = this.versionParts.get(i);
final String otherPart = other.versionParts.get(i);
if (!thisPart.equals(otherPart)) {
public boolean matchesAtLeastThreeLevels(DependencyVersion version) {
if (version == null) {
if (Math.abs(this.versionParts.size() - version.versionParts.size()) >= 3) {
final int max = (this.versionParts.size() < version.versionParts.size())
? this.versionParts.size() : version.versionParts.size();
boolean ret = true;
final String thisVersion = this.versionParts.get(i);
final String otherVersion = version.getVersionParts().get(i);
if (i >= 3) {
if (thisVersion.compareToIgnoreCase(otherVersion) >= 0) {
ret = false;
} else if (!thisVersion.equals(otherVersion)) {
return ret;
public static DependencyVersion parseVersion(String text) {
//'-' is a special case used within the CVE entries, just include it as the version.
if ("-".equals(text)) {
final DependencyVersion dv = new DependencyVersion();
list.add(text);
return dv;
String version = null;
Matcher matcher = RX_VERSION.matcher(text);
if (matcher.find()) {
version = matcher.group();
//throw away the results if there are two things that look like version numbers
matcher = RX_SINGLE_VERSION.matcher(text);
if (version != null && version.endsWith("-py2") && version.length() > 4) {
version = version.substring(0, version.length() - 4);
return new DependencyVersion(version);
public Iterator<T> filter(Iterator<T> iterator) {
return new FilterIterator(iterator);
public Iterable<T> filter(final Iterable<T> iterable) {
return new Iterable<T>() {
public Iterator<T> iterator() {
return filter(iterable.iterator());
private T next;
private FilterIterator(Iterator<T> iterator) {
this.iterator = iterator;
toNext();
public boolean hasNext() {
return next != null;
public T next() {
if (next == null) {
throw new NoSuchElementException();
T returnValue = next;
return returnValue;
private void toNext() {
next = null;
while (iterator.hasNext()) {
T item = iterator.next();
if (item != null && passes(item)) {
next = item;
* @param right the value for the right pair
public Pair(L left, R right) {
this.left = left;
this.right = right;
* The left element of the pair.
private L left = null;
public L getLeft() {
return left;
* The right element of the pair.
private R right = null;
public R getRight() {
return right;
int hash = 3;
hash = 53 * hash + (this.left != null ? this.left.hashCode() : 0);
hash = 53 * hash + (this.right != null ? this.right.hashCode() : 0);
public static boolean containsUrl(String text) {
return CONTAINS_URL_TEST.matcher(text).matches();
public static boolean isUrl(String text) {
return IS_URL_TEST.matcher(text).matches();
public static List<String> extractImportantUrlData(String text) throws MalformedURLException {
final List<String> importantParts = new ArrayList<String>();
final URL url = new URL(text);
final String[] domain = url.getHost().split("\\.");
//add the domain except www and the tld.
for (int i = 0; i < domain.length - 1; i++) {
final String sub = domain[i];
if (!IGNORE_LIST.contains(sub.toLowerCase())) {
importantParts.add(sub);
final String document = url.getPath();
final String[] pathParts = document.split("[\\//]");
for (int i = 0; i < pathParts.length - 2; i++) {
if (!pathParts[i].isEmpty()) {
importantParts.add(pathParts[i]);
if (pathParts.length > 0 && !pathParts[pathParts.length - 1].isEmpty()) {
final String fileNameNoExt = pathParts[pathParts.length - 1].replaceAll("\\..*{0,5}$", "");
importantParts.add(fileNameNoExt);
return importantParts;
In addition to the above, the dependencyCheck plugin can be configured to enable or disable specific analyzers by configuring the analyzer section. Note, specific file type analyzers will automatically disable themselves if no file types that they support are detected - so specifically disabling the analyzers is likely not needed.
In addition to the above, the dependencyCheck plugin can be configured to enable or disable specific analyzers by configuring the analyzers section. Note, specific file type analyzers will automatically disable themselves if no file types that they support are detected - so specifically disabling the analyzers is likely not needed.
dependencyCheck { - analyzer { + analyzers { assemblyEnabled=false } } diff --git a/dependency-check-gradle/index.html b/dependency-check-gradle/index.html index 86e1f20d3..6a728dde7 100644 --- a/dependency-check-gradle/index.html +++ b/dependency-check-gradle/index.html @@ -1,15 +1,15 @@ - + - dependency-check – Usage + dependency-check-gradle – Usage @@ -62,9 +62,9 @@ -
Full name:
org.owasp:dependency-check-maven:1.3.2:aggregate
org.owasp:dependency-check-maven:1.3.3:aggregate
Description:
org.owasp:dependency-check-maven:1.3.2:check
org.owasp:dependency-check-maven:1.3.3:check
if (log != null) {
log.debug(msg);
System.out.println(msg);
org.owasp:dependency-check-maven:1.3.2:help
org.owasp:dependency-check-maven:1.3.3:help
org.owasp:dependency-check-maven:1.3.2:purge
org.owasp:dependency-check-maven:1.3.3:purge
org.owasp:dependency-check-maven:1.3.2:update-only
org.owasp:dependency-check-maven:1.3.3:update-only