mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-03-26 02:51:27 +01:00
refactored the dependency object to be threadsafe
This commit is contained in:
@@ -266,7 +266,7 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
d.getFileName());
|
d.getFileName());
|
||||||
d.setFilePath(displayPath);
|
d.setFilePath(displayPath);
|
||||||
d.setFileName(displayName);
|
d.setFileName(displayName);
|
||||||
d.setProjectReferences(dependency.getProjectReferences());
|
d.addAllProjectReferences(dependency.getProjectReferences());
|
||||||
|
|
||||||
//TODO - can we get more evidence from the parent? EAR contains module name, etc.
|
//TODO - can we get more evidence from the parent? EAR contains module name, etc.
|
||||||
//analyze the dependency (i.e. extract files) if it is a supported type.
|
//analyze the dependency (i.e. extract files) if it is a supported type.
|
||||||
|
|||||||
@@ -120,11 +120,11 @@ public class DependencyBundlingAnalyzer extends AbstractDependencyComparingAnaly
|
|||||||
} else if (isShadedJar(dependency, nextDependency)) {
|
} else if (isShadedJar(dependency, nextDependency)) {
|
||||||
if (dependency.getFileName().toLowerCase().endsWith("pom.xml")) {
|
if (dependency.getFileName().toLowerCase().endsWith("pom.xml")) {
|
||||||
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
mergeDependencies(nextDependency, dependency, dependenciesToRemove);
|
||||||
nextDependency.getRelatedDependencies().remove(dependency);
|
nextDependency.removeRelatedDependencies(dependency);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
||||||
dependency.getRelatedDependencies().remove(nextDependency);
|
dependency.removeRelatedDependencies(nextDependency);
|
||||||
}
|
}
|
||||||
} else if (cpeIdentifiersMatch(dependency, nextDependency)
|
} else if (cpeIdentifiersMatch(dependency, nextDependency)
|
||||||
&& hasSameBasePath(dependency, nextDependency)
|
&& hasSameBasePath(dependency, nextDependency)
|
||||||
@@ -152,10 +152,9 @@ public class DependencyBundlingAnalyzer extends AbstractDependencyComparingAnaly
|
|||||||
*/
|
*/
|
||||||
private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set<Dependency> dependenciesToRemove) {
|
private void mergeDependencies(final Dependency dependency, final Dependency relatedDependency, final Set<Dependency> dependenciesToRemove) {
|
||||||
dependency.addRelatedDependency(relatedDependency);
|
dependency.addRelatedDependency(relatedDependency);
|
||||||
final Iterator<Dependency> i = relatedDependency.getRelatedDependencies().iterator();
|
for (Dependency d : relatedDependency.getRelatedDependencies()) {
|
||||||
while (i.hasNext()) {
|
dependency.addRelatedDependency(d);
|
||||||
dependency.addRelatedDependency(i.next());
|
relatedDependency.removeRelatedDependencies(d);
|
||||||
i.remove();
|
|
||||||
}
|
}
|
||||||
if (dependency.getSha1sum().equals(relatedDependency.getSha1sum())) {
|
if (dependency.getSha1sum().equals(relatedDependency.getSha1sum())) {
|
||||||
dependency.addAllProjectReferences(relatedDependency.getProjectReferences());
|
dependency.addAllProjectReferences(relatedDependency.getProjectReferences());
|
||||||
|
|||||||
@@ -132,10 +132,9 @@ public class DependencyMergingAnalyzer extends AbstractDependencyComparingAnalyz
|
|||||||
dependency.addEvidence(EvidenceType.VERSION, e);
|
dependency.addEvidence(EvidenceType.VERSION, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Iterator<Dependency> i = relatedDependency.getRelatedDependencies().iterator();
|
for (Dependency d : relatedDependency.getRelatedDependencies()) {
|
||||||
while (i.hasNext()) {
|
dependency.addRelatedDependency(d);
|
||||||
dependency.addRelatedDependency(i.next());
|
relatedDependency.removeRelatedDependencies(d);
|
||||||
i.remove();
|
|
||||||
}
|
}
|
||||||
if (dependency.getSha1sum().equals(relatedDependency.getSha1sum())) {
|
if (dependency.getSha1sum().equals(relatedDependency.getSha1sum())) {
|
||||||
dependency.addAllProjectReferences(relatedDependency.getProjectReferences());
|
dependency.addAllProjectReferences(relatedDependency.getProjectReferences());
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.io.UnsupportedEncodingException;
|
|||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
@@ -160,17 +161,18 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mustContain != null) {
|
if (mustContain != null) {
|
||||||
final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
|
final Set<Identifier> removalSet = new HashSet<>();
|
||||||
while (itr.hasNext()) {
|
for (Identifier i : dependency.getIdentifiers()) {
|
||||||
final Identifier i = itr.next();
|
|
||||||
if ("cpe".contains(i.getType())
|
if ("cpe".contains(i.getType())
|
||||||
&& i.getValue() != null
|
&& i.getValue() != null
|
||||||
&& i.getValue().startsWith("cpe:/a:springsource:")
|
&& i.getValue().startsWith("cpe:/a:springsource:")
|
||||||
&& !i.getValue().toLowerCase().contains(mustContain)) {
|
&& !i.getValue().toLowerCase().contains(mustContain)) {
|
||||||
itr.remove();
|
removalSet.add(i);
|
||||||
//dependency.getIdentifiers().remove(i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (Identifier i : removalSet) {
|
||||||
|
dependency.removeIdentifier(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,15 +223,15 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
//how did we get here?
|
//how did we get here?
|
||||||
LOGGER.debug("currentVersion and nextVersion are both null?");
|
LOGGER.debug("currentVersion and nextVersion are both null?");
|
||||||
} else if (currentVersion == null && nextVersion != null) {
|
} else if (currentVersion == null && nextVersion != null) {
|
||||||
dependency.getIdentifiers().remove(currentId);
|
dependency.removeIdentifier(currentId);
|
||||||
} else if (nextVersion == null && currentVersion != null) {
|
} else if (nextVersion == null && currentVersion != null) {
|
||||||
dependency.getIdentifiers().remove(nextId);
|
dependency.removeIdentifier(nextId);
|
||||||
} else if (currentVersion.length() < nextVersion.length()) {
|
} else if (currentVersion.length() < nextVersion.length()) {
|
||||||
if (nextVersion.startsWith(currentVersion) || "-".equals(currentVersion)) {
|
if (nextVersion.startsWith(currentVersion) || "-".equals(currentVersion)) {
|
||||||
dependency.getIdentifiers().remove(currentId);
|
dependency.removeIdentifier(currentId);
|
||||||
}
|
}
|
||||||
} else if (currentVersion.startsWith(nextVersion) || "-".equals(nextVersion)) {
|
} else if (currentVersion.startsWith(nextVersion) || "-".equals(nextVersion)) {
|
||||||
dependency.getIdentifiers().remove(nextId);
|
dependency.removeIdentifier(nextId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -244,21 +246,22 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
* @param dependency the dependency to remove JRE CPEs from
|
* @param dependency the dependency to remove JRE CPEs from
|
||||||
*/
|
*/
|
||||||
private void removeJreEntries(Dependency dependency) {
|
private void removeJreEntries(Dependency dependency) {
|
||||||
final Set<Identifier> identifiers = dependency.getIdentifiers();
|
final Set<Identifier> removalSet = new HashSet<>();
|
||||||
final Iterator<Identifier> itr = identifiers.iterator();
|
for (Identifier i : dependency.getIdentifiers()) {
|
||||||
while (itr.hasNext()) {
|
|
||||||
final Identifier i = itr.next();
|
|
||||||
final Matcher coreCPE = CORE_JAVA.matcher(i.getValue());
|
final Matcher coreCPE = CORE_JAVA.matcher(i.getValue());
|
||||||
final Matcher coreFiles = CORE_FILES.matcher(dependency.getFileName());
|
final Matcher coreFiles = CORE_FILES.matcher(dependency.getFileName());
|
||||||
if (coreCPE.matches() && !coreFiles.matches()) {
|
if (coreCPE.matches() && !coreFiles.matches()) {
|
||||||
itr.remove();
|
removalSet.add(i);
|
||||||
}
|
}
|
||||||
final Matcher coreJsfCPE = CORE_JAVA_JSF.matcher(i.getValue());
|
final Matcher coreJsfCPE = CORE_JAVA_JSF.matcher(i.getValue());
|
||||||
final Matcher coreJsfFiles = CORE_JSF_FILES.matcher(dependency.getFileName());
|
final Matcher coreJsfFiles = CORE_JSF_FILES.matcher(dependency.getFileName());
|
||||||
if (coreJsfCPE.matches() && !coreJsfFiles.matches()) {
|
if (coreJsfCPE.matches() && !coreJsfFiles.matches()) {
|
||||||
itr.remove();
|
removalSet.add(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (Identifier i : removalSet) {
|
||||||
|
dependency.removeIdentifier(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -290,8 +293,6 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
* @param dependency the dependency to analyze
|
* @param dependency the dependency to analyze
|
||||||
*/
|
*/
|
||||||
protected void removeBadMatches(Dependency dependency) {
|
protected void removeBadMatches(Dependency dependency) {
|
||||||
final Set<Identifier> identifiers = dependency.getIdentifiers();
|
|
||||||
final Iterator<Identifier> itr = identifiers.iterator();
|
|
||||||
|
|
||||||
/* TODO - can we utilize the pom's groupid and artifactId to filter??? most of
|
/* TODO - can we utilize the pom's groupid and artifactId to filter??? most of
|
||||||
* these are due to low quality data. Other idea would be to say any CPE
|
* these are due to low quality data. Other idea would be to say any CPE
|
||||||
@@ -300,8 +301,7 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
*/
|
*/
|
||||||
//Set<Evidence> groupId = dependency.getVendorEvidence().getEvidence("pom", "groupid");
|
//Set<Evidence> groupId = dependency.getVendorEvidence().getEvidence("pom", "groupid");
|
||||||
//Set<Evidence> artifactId = dependency.getVendorEvidence().getEvidence("pom", "artifactid");
|
//Set<Evidence> artifactId = dependency.getVendorEvidence().getEvidence("pom", "artifactid");
|
||||||
while (itr.hasNext()) {
|
for (Identifier i : dependency.getIdentifiers()) {
|
||||||
final Identifier i = itr.next();
|
|
||||||
//TODO move this startsWith expression to the base suppression file
|
//TODO move this startsWith expression to the base suppression file
|
||||||
if ("cpe".equals(i.getType())) {
|
if ("cpe".equals(i.getType())) {
|
||||||
if ((i.getValue().matches(".*c\\+\\+.*")
|
if ((i.getValue().matches(".*c\\+\\+.*")
|
||||||
@@ -325,7 +325,8 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
|| dependency.getFileName().toLowerCase().endsWith(".tgz")
|
|| dependency.getFileName().toLowerCase().endsWith(".tgz")
|
||||||
|| dependency.getFileName().toLowerCase().endsWith(".ear")
|
|| dependency.getFileName().toLowerCase().endsWith(".ear")
|
||||||
|| dependency.getFileName().toLowerCase().endsWith(".war"))) {
|
|| dependency.getFileName().toLowerCase().endsWith(".war"))) {
|
||||||
itr.remove();
|
//itr.remove();
|
||||||
|
dependency.removeIdentifier(i);
|
||||||
} else if ((i.getValue().startsWith("cpe:/a:jquery:jquery")
|
} else if ((i.getValue().startsWith("cpe:/a:jquery:jquery")
|
||||||
|| i.getValue().startsWith("cpe:/a:prototypejs:prototype")
|
|| i.getValue().startsWith("cpe:/a:prototypejs:prototype")
|
||||||
|| i.getValue().startsWith("cpe:/a:yahoo:yui"))
|
|| i.getValue().startsWith("cpe:/a:yahoo:yui"))
|
||||||
@@ -333,7 +334,8 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
|| dependency.getFileName().toLowerCase().endsWith("pom.xml")
|
|| dependency.getFileName().toLowerCase().endsWith("pom.xml")
|
||||||
|| dependency.getFileName().toLowerCase().endsWith(".dll")
|
|| dependency.getFileName().toLowerCase().endsWith(".dll")
|
||||||
|| dependency.getFileName().toLowerCase().endsWith(".exe"))) {
|
|| dependency.getFileName().toLowerCase().endsWith(".exe"))) {
|
||||||
itr.remove();
|
//itr.remove();
|
||||||
|
dependency.removeIdentifier(i);
|
||||||
} else if ((i.getValue().startsWith("cpe:/a:microsoft:excel")
|
} else if ((i.getValue().startsWith("cpe:/a:microsoft:excel")
|
||||||
|| i.getValue().startsWith("cpe:/a:microsoft:word")
|
|| i.getValue().startsWith("cpe:/a:microsoft:word")
|
||||||
|| i.getValue().startsWith("cpe:/a:microsoft:visio")
|
|| i.getValue().startsWith("cpe:/a:microsoft:visio")
|
||||||
@@ -344,10 +346,12 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
|| dependency.getFileName().toLowerCase().endsWith(".ear")
|
|| dependency.getFileName().toLowerCase().endsWith(".ear")
|
||||||
|| dependency.getFileName().toLowerCase().endsWith(".war")
|
|| dependency.getFileName().toLowerCase().endsWith(".war")
|
||||||
|| dependency.getFileName().toLowerCase().endsWith("pom.xml"))) {
|
|| dependency.getFileName().toLowerCase().endsWith("pom.xml"))) {
|
||||||
itr.remove();
|
//itr.remove();
|
||||||
|
dependency.removeIdentifier(i);
|
||||||
} else if (i.getValue().startsWith("cpe:/a:apache:maven")
|
} else if (i.getValue().startsWith("cpe:/a:apache:maven")
|
||||||
&& !dependency.getFileName().toLowerCase().matches("maven-core-[\\d\\.]+\\.jar")) {
|
&& !dependency.getFileName().toLowerCase().matches("maven-core-[\\d\\.]+\\.jar")) {
|
||||||
itr.remove();
|
//itr.remove();
|
||||||
|
dependency.removeIdentifier(i);
|
||||||
} else if (i.getValue().startsWith("cpe:/a:m-core:m-core")) {
|
} else if (i.getValue().startsWith("cpe:/a:m-core:m-core")) {
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (Evidence e : dependency.getEvidence(EvidenceType.PRODUCT)) {
|
for (Evidence e : dependency.getEvidence(EvidenceType.PRODUCT)) {
|
||||||
@@ -365,11 +369,13 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
itr.remove();
|
//itr.remove();
|
||||||
|
dependency.removeIdentifier(i);
|
||||||
}
|
}
|
||||||
} else if (i.getValue().startsWith("cpe:/a:jboss:jboss")
|
} else if (i.getValue().startsWith("cpe:/a:jboss:jboss")
|
||||||
&& !dependency.getFileName().toLowerCase().matches("jboss-?[\\d\\.-]+(GA)?\\.jar")) {
|
&& !dependency.getFileName().toLowerCase().matches("jboss-?[\\d\\.-]+(GA)?\\.jar")) {
|
||||||
itr.remove();
|
//itr.remove();
|
||||||
|
dependency.removeIdentifier(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -382,31 +388,30 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
* @param dependency the dependency to analyze
|
* @param dependency the dependency to analyze
|
||||||
*/
|
*/
|
||||||
private void removeWrongVersionMatches(Dependency dependency) {
|
private void removeWrongVersionMatches(Dependency dependency) {
|
||||||
final Set<Identifier> identifiers = dependency.getIdentifiers();
|
final Set<Identifier> identifiersToRemove = new HashSet<>();
|
||||||
final Iterator<Identifier> itr = identifiers.iterator();
|
|
||||||
|
|
||||||
final String fileName = dependency.getFileName();
|
final String fileName = dependency.getFileName();
|
||||||
if (fileName != null && fileName.contains("axis2")) {
|
if (fileName != null && fileName.contains("axis2")) {
|
||||||
while (itr.hasNext()) {
|
for (Identifier i : dependency.getIdentifiers()) {
|
||||||
final Identifier i = itr.next();
|
|
||||||
if ("cpe".equals(i.getType())) {
|
if ("cpe".equals(i.getType())) {
|
||||||
final String cpe = i.getValue();
|
final String cpe = i.getValue();
|
||||||
if (cpe != null && (cpe.startsWith("cpe:/a:apache:axis:") || "cpe:/a:apache:axis".equals(cpe))) {
|
if (cpe != null && (cpe.startsWith("cpe:/a:apache:axis:") || "cpe:/a:apache:axis".equals(cpe))) {
|
||||||
itr.remove();
|
identifiersToRemove.add(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (fileName != null && fileName.contains("axis")) {
|
} else if (fileName != null && fileName.contains("axis")) {
|
||||||
while (itr.hasNext()) {
|
for (Identifier i : dependency.getIdentifiers()) {
|
||||||
final Identifier i = itr.next();
|
|
||||||
if ("cpe".equals(i.getType())) {
|
if ("cpe".equals(i.getType())) {
|
||||||
final String cpe = i.getValue();
|
final String cpe = i.getValue();
|
||||||
if (cpe != null && (cpe.startsWith("cpe:/a:apache:axis2:") || "cpe:/a:apache:axis2".equals(cpe))) {
|
if (cpe != null && (cpe.startsWith("cpe:/a:apache:axis2:") || "cpe:/a:apache:axis2".equals(cpe))) {
|
||||||
itr.remove();
|
identifiersToRemove.add(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (Identifier i : identifiersToRemove) {
|
||||||
|
dependency.removeIdentifier(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -430,17 +435,13 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
final String newCpe3 = String.format("cpe:/a:sun:opensso:%s", identifier.getValue().substring(22));
|
final String newCpe3 = String.format("cpe:/a:sun:opensso:%s", identifier.getValue().substring(22));
|
||||||
final String newCpe4 = String.format("cpe:/a:oracle:opensso:%s", identifier.getValue().substring(22));
|
final String newCpe4 = String.format("cpe:/a:oracle:opensso:%s", identifier.getValue().substring(22));
|
||||||
try {
|
try {
|
||||||
dependency.addIdentifier("cpe",
|
dependency.addIdentifier("cpe", newCpe,
|
||||||
newCpe,
|
|
||||||
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe, "UTF-8")));
|
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe, "UTF-8")));
|
||||||
dependency.addIdentifier("cpe",
|
dependency.addIdentifier("cpe", newCpe2,
|
||||||
newCpe2,
|
|
||||||
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe2, "UTF-8")));
|
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe2, "UTF-8")));
|
||||||
dependency.addIdentifier("cpe",
|
dependency.addIdentifier("cpe", newCpe3,
|
||||||
newCpe3,
|
|
||||||
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe3, "UTF-8")));
|
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe3, "UTF-8")));
|
||||||
dependency.addIdentifier("cpe",
|
dependency.addIdentifier("cpe", newCpe4,
|
||||||
newCpe4,
|
|
||||||
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe4, "UTF-8")));
|
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe4, "UTF-8")));
|
||||||
} catch (UnsupportedEncodingException ex) {
|
} catch (UnsupportedEncodingException ex) {
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ public class NspAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
vuln.setVulnerableSoftware(new HashSet<>(Arrays.asList(vs)));
|
vuln.setVulnerableSoftware(new HashSet<>(Arrays.asList(vs)));
|
||||||
|
|
||||||
// Add the vulnerability to package.json
|
// Add the vulnerability to package.json
|
||||||
dependency.getVulnerabilities().add(vuln);
|
dependency.addVulnerability(vuln);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -323,9 +323,12 @@ public class NspAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
* dependency will not actually exist but needs to be unique (due to the use of Set in Dependency).
|
* dependency will not actually exist but needs to be unique (due to the use of Set in Dependency).
|
||||||
* The use of related dependencies is a way to specify the actual software BOM in package.json.
|
* The use of related dependencies is a way to specify the actual software BOM in package.json.
|
||||||
*/
|
*/
|
||||||
|
//TODO is this actually correct? or should these be transitive dependencies?
|
||||||
final Dependency nodeModule = new Dependency(new File(dependency.getActualFile() + "#" + entry.getKey()), true);
|
final Dependency nodeModule = new Dependency(new File(dependency.getActualFile() + "#" + entry.getKey()), true);
|
||||||
nodeModule.setDisplayFileName(entry.getKey());
|
nodeModule.setDisplayFileName(entry.getKey());
|
||||||
nodeModule.setIdentifiers(new HashSet<>(Arrays.asList(moduleName, moduleVersion, moduleDepType)));
|
nodeModule.addIdentifier(moduleName);
|
||||||
|
nodeModule.addIdentifier(moduleVersion);
|
||||||
|
nodeModule.addIdentifier(moduleDepType);
|
||||||
dependency.addRelatedDependency(nodeModule);
|
dependency.addRelatedDependency(nodeModule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public class NvdCveAnalyzer extends AbstractAnalyzer {
|
|||||||
try {
|
try {
|
||||||
final String value = id.getValue();
|
final String value = id.getValue();
|
||||||
final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
|
final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
|
||||||
dependency.getVulnerabilities().addAll(vulns);
|
dependency.addVulnerabilities(vulns);
|
||||||
} catch (DatabaseException ex) {
|
} catch (DatabaseException ex) {
|
||||||
throw new AnalysisException(ex);
|
throw new AnalysisException(ex);
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ public class NvdCveAnalyzer extends AbstractAnalyzer {
|
|||||||
try {
|
try {
|
||||||
final String value = id.getValue();
|
final String value = id.getValue();
|
||||||
final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
|
final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
|
||||||
dependency.getSuppressedVulnerabilities().addAll(vulns);
|
dependency.addSuppressedVulnerabilities(vulns);
|
||||||
} catch (DatabaseException ex) {
|
} catch (DatabaseException ex) {
|
||||||
throw new AnalysisException(ex);
|
throw new AnalysisException(ex);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
vulnerability.setName(advisory);
|
vulnerability.setName(advisory);
|
||||||
}
|
}
|
||||||
if (null != dependency) {
|
if (null != dependency) {
|
||||||
dependency.getVulnerabilities().add(vulnerability); // needed to wait for vulnerability name to avoid NPE
|
dependency.addVulnerability(vulnerability);
|
||||||
}
|
}
|
||||||
LOGGER.debug("bundle-audit ({}): {}", parentName, nextLine);
|
LOGGER.debug("bundle-audit ({}): {}", parentName, nextLine);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,12 +22,13 @@ import java.io.IOException;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
|
|
||||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||||
@@ -44,7 +45,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
*
|
*
|
||||||
* @author Jeremy Long
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
@NotThreadSafe
|
@ThreadSafe
|
||||||
public class Dependency extends EvidenceCollection implements Serializable, Comparable<Dependency> {
|
public class Dependency extends EvidenceCollection implements Serializable, Comparable<Dependency> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,7 +83,7 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
/**
|
/**
|
||||||
* A list of Identifiers.
|
* A list of Identifiers.
|
||||||
*/
|
*/
|
||||||
private Set<Identifier> identifiers = new TreeSet<>();
|
private final Set<Identifier> identifiers = new TreeSet<>();
|
||||||
/**
|
/**
|
||||||
* The file name to display in reports.
|
* The file name to display in reports.
|
||||||
*/
|
*/
|
||||||
@@ -90,11 +91,11 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
/**
|
/**
|
||||||
* A set of identifiers that have been suppressed.
|
* A set of identifiers that have been suppressed.
|
||||||
*/
|
*/
|
||||||
private Set<Identifier> suppressedIdentifiers = new TreeSet<>();
|
private final Set<Identifier> suppressedIdentifiers = new TreeSet<>();
|
||||||
/**
|
/**
|
||||||
* A set of vulnerabilities that have been suppressed.
|
* A set of vulnerabilities that have been suppressed.
|
||||||
*/
|
*/
|
||||||
private SortedSet<Vulnerability> suppressedVulnerabilities = new TreeSet<>(new VulnerabilityComparator());
|
private final SortedSet<Vulnerability> suppressedVulnerabilities = new TreeSet<>(new VulnerabilityComparator());
|
||||||
/**
|
/**
|
||||||
* The description of the JAR file.
|
* The description of the JAR file.
|
||||||
*/
|
*/
|
||||||
@@ -106,19 +107,19 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
/**
|
/**
|
||||||
* A list of vulnerabilities for this dependency.
|
* A list of vulnerabilities for this dependency.
|
||||||
*/
|
*/
|
||||||
private SortedSet<Vulnerability> vulnerabilities = new TreeSet<>(new VulnerabilityComparator());
|
private final SortedSet<Vulnerability> vulnerabilities = new TreeSet<>(new VulnerabilityComparator());
|
||||||
/**
|
/**
|
||||||
* A collection of related dependencies.
|
* A collection of related dependencies.
|
||||||
*/
|
*/
|
||||||
private Set<Dependency> relatedDependencies = new TreeSet<>();
|
private final Set<Dependency> relatedDependencies = new TreeSet<>();
|
||||||
/**
|
/**
|
||||||
* A list of projects that reference this dependency.
|
* A list of projects that reference this dependency.
|
||||||
*/
|
*/
|
||||||
private Set<String> projectReferences = new HashSet<>();
|
private final Set<String> projectReferences = new HashSet<>();
|
||||||
/**
|
/**
|
||||||
* A list of available versions.
|
* A list of available versions.
|
||||||
*/
|
*/
|
||||||
private List<String> availableVersions = new ArrayList<>();
|
private final List<String> availableVersions = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines an actual or virtual dependency.
|
* Defines an actual or virtual dependency.
|
||||||
@@ -322,21 +323,22 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a List of Identifiers.
|
* Returns an unmodifiable List of Identifiers.
|
||||||
*
|
*
|
||||||
* @return an ArrayList of Identifiers
|
* @return an unmodifiable List of Identifiers
|
||||||
*/
|
*/
|
||||||
public Set<Identifier> getIdentifiers() {
|
public synchronized Set<Identifier> getIdentifiers() {
|
||||||
return this.identifiers;
|
return Collections.unmodifiableSet(new HashSet<>(identifiers));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a List of Identifiers.
|
* Adds a set of Identifiers to the current list of identifiers. Only used
|
||||||
|
* for testing.
|
||||||
*
|
*
|
||||||
* @param identifiers A list of Identifiers
|
* @param identifiers A set of Identifiers
|
||||||
*/
|
*/
|
||||||
public void setIdentifiers(Set<Identifier> identifiers) {
|
protected synchronized void addIdentifiers(Set<Identifier> identifiers) {
|
||||||
this.identifiers = identifiers;
|
this.identifiers.addAll(identifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -347,7 +349,7 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
* @param value the value of the identifier
|
* @param value the value of the identifier
|
||||||
* @param url the URL of the identifier
|
* @param url the URL of the identifier
|
||||||
*/
|
*/
|
||||||
public void addIdentifier(String type, String value, String url) {
|
public synchronized void addIdentifier(String type, String value, String url) {
|
||||||
final Identifier i = new Identifier(type, value, url);
|
final Identifier i = new Identifier(type, value, url);
|
||||||
this.identifiers.add(i);
|
this.identifiers.add(i);
|
||||||
}
|
}
|
||||||
@@ -361,12 +363,21 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
* @param url the URL of the identifier
|
* @param url the URL of the identifier
|
||||||
* @param confidence the confidence in the Identifier being accurate
|
* @param confidence the confidence in the Identifier being accurate
|
||||||
*/
|
*/
|
||||||
public void addIdentifier(String type, String value, String url, Confidence confidence) {
|
public synchronized void addIdentifier(String type, String value, String url, Confidence confidence) {
|
||||||
final Identifier i = new Identifier(type, value, url);
|
final Identifier i = new Identifier(type, value, url);
|
||||||
i.setConfidence(confidence);
|
i.setConfidence(confidence);
|
||||||
this.identifiers.add(i);
|
this.identifiers.add(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an identifier from the list of identifiers.
|
||||||
|
*
|
||||||
|
* @param i the identifier to remove
|
||||||
|
*/
|
||||||
|
public synchronized void removeIdentifier(Identifier i) {
|
||||||
|
this.identifiers.remove(i);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the maven artifact as evidence.
|
* Adds the maven artifact as evidence.
|
||||||
*
|
*
|
||||||
@@ -386,15 +397,17 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
}
|
}
|
||||||
if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) {
|
if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) {
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (Identifier i : this.getIdentifiers()) {
|
synchronized (this) {
|
||||||
if ("maven".equals(i.getType()) && i.getValue().equals(mavenArtifact.toString())) {
|
for (Identifier i : this.identifiers) {
|
||||||
found = true;
|
if ("maven".equals(i.getType()) && i.getValue().equals(mavenArtifact.toString())) {
|
||||||
i.setConfidence(Confidence.HIGHEST);
|
found = true;
|
||||||
final String url = "http://search.maven.org/#search|ga|1|1%3A%22" + this.getSha1sum() + "%22";
|
i.setConfidence(Confidence.HIGHEST);
|
||||||
i.setUrl(url);
|
final String url = "http://search.maven.org/#search|ga|1|1%3A%22" + this.getSha1sum() + "%22";
|
||||||
//i.setUrl(mavenArtifact.getArtifactUrl());
|
i.setUrl(url);
|
||||||
LOGGER.debug("Already found identifier {}. Confidence set to highest", i.getValue());
|
//i.setUrl(mavenArtifact.getArtifactUrl());
|
||||||
break;
|
LOGGER.debug("Already found identifier {}. Confidence set to highest", i.getValue());
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
@@ -410,26 +423,17 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
*
|
*
|
||||||
* @param identifier the identifier to add
|
* @param identifier the identifier to add
|
||||||
*/
|
*/
|
||||||
public void addIdentifier(Identifier identifier) {
|
public synchronized void addIdentifier(Identifier identifier) {
|
||||||
this.identifiers.add(identifier);
|
this.identifiers.add(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of suppressedIdentifiers.
|
* Get the unmodifiable set of suppressedIdentifiers.
|
||||||
*
|
*
|
||||||
* @return the value of suppressedIdentifiers
|
* @return the value of suppressedIdentifiers
|
||||||
*/
|
*/
|
||||||
public Set<Identifier> getSuppressedIdentifiers() {
|
public synchronized Set<Identifier> getSuppressedIdentifiers() {
|
||||||
return suppressedIdentifiers;
|
return Collections.unmodifiableSet(new HashSet<>(suppressedIdentifiers));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value of suppressedIdentifiers.
|
|
||||||
*
|
|
||||||
* @param suppressedIdentifiers new value of suppressedIdentifiers
|
|
||||||
*/
|
|
||||||
public void setSuppressedIdentifiers(Set<Identifier> suppressedIdentifiers) {
|
|
||||||
this.suppressedIdentifiers = suppressedIdentifiers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -437,26 +441,17 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
*
|
*
|
||||||
* @param identifier an identifier that was suppressed.
|
* @param identifier an identifier that was suppressed.
|
||||||
*/
|
*/
|
||||||
public void addSuppressedIdentifier(Identifier identifier) {
|
public synchronized void addSuppressedIdentifier(Identifier identifier) {
|
||||||
this.suppressedIdentifiers.add(identifier);
|
this.suppressedIdentifiers.add(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of suppressedVulnerabilities.
|
* Get an unmodifiable sorted set of suppressedVulnerabilities.
|
||||||
*
|
*
|
||||||
* @return the value of suppressedVulnerabilities
|
* @return the unmodifiable sorted set of suppressedVulnerabilities
|
||||||
*/
|
*/
|
||||||
public SortedSet<Vulnerability> getSuppressedVulnerabilities() {
|
public synchronized SortedSet<Vulnerability> getSuppressedVulnerabilities() {
|
||||||
return suppressedVulnerabilities;
|
return Collections.unmodifiableSortedSet(new TreeSet<>(suppressedVulnerabilities));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value of suppressedVulnerabilities.
|
|
||||||
*
|
|
||||||
* @param suppressedVulnerabilities new value of suppressedVulnerabilities
|
|
||||||
*/
|
|
||||||
public void setSuppressedVulnerabilities(SortedSet<Vulnerability> suppressedVulnerabilities) {
|
|
||||||
this.suppressedVulnerabilities = suppressedVulnerabilities;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -464,7 +459,7 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
*
|
*
|
||||||
* @param vulnerability the vulnerability that was suppressed
|
* @param vulnerability the vulnerability that was suppressed
|
||||||
*/
|
*/
|
||||||
public void addSuppressedVulnerability(Vulnerability vulnerability) {
|
public synchronized void addSuppressedVulnerability(Vulnerability vulnerability) {
|
||||||
this.suppressedVulnerabilities.add(vulnerability);
|
this.suppressedVulnerabilities.add(vulnerability);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,21 +500,12 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of vulnerabilities.
|
* Get the unmodifiable sorted set of vulnerabilities.
|
||||||
*
|
*
|
||||||
* @return the list of vulnerabilities
|
* @return the unmodifiable sorted set of vulnerabilities
|
||||||
*/
|
*/
|
||||||
public SortedSet<Vulnerability> getVulnerabilities() {
|
public synchronized SortedSet<Vulnerability> getVulnerabilities() {
|
||||||
return vulnerabilities;
|
return Collections.unmodifiableSortedSet(new TreeSet<>(vulnerabilities));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value of vulnerabilities.
|
|
||||||
*
|
|
||||||
* @param vulnerabilities new value of vulnerabilities
|
|
||||||
*/
|
|
||||||
public void setVulnerabilities(SortedSet<Vulnerability> vulnerabilities) {
|
|
||||||
this.vulnerabilities = vulnerabilities;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -550,39 +536,48 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
/**
|
/**
|
||||||
* Adds a vulnerability to the dependency.
|
* Adds a vulnerability to the dependency.
|
||||||
*
|
*
|
||||||
* @param vulnerability a vulnerability outlining a vulnerability.
|
* @param vulnerability a vulnerability
|
||||||
*/
|
*/
|
||||||
public void addVulnerability(Vulnerability vulnerability) {
|
public synchronized void addVulnerability(Vulnerability vulnerability) {
|
||||||
this.vulnerabilities.add(vulnerability);
|
this.vulnerabilities.add(vulnerability);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of {@link #relatedDependencies}. This field is used to
|
* Adds a list of vulnerabilities to the dependency.
|
||||||
* collect other dependencies which really represent the same dependency,
|
|
||||||
* and may be presented as one item in reports.
|
|
||||||
*
|
*
|
||||||
* @return the value of relatedDependencies
|
* @param vulnerabilities a list of vulnerabilities
|
||||||
*/
|
*/
|
||||||
public Set<Dependency> getRelatedDependencies() {
|
public synchronized void addVulnerabilities(List<Vulnerability> vulnerabilities) {
|
||||||
return relatedDependencies;
|
this.vulnerabilities.addAll(vulnerabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of projectReferences.
|
* Removes the given vulnerability from the list.
|
||||||
*
|
*
|
||||||
* @return the value of projectReferences
|
* @param v the vulnerability to remove
|
||||||
*/
|
*/
|
||||||
public Set<String> getProjectReferences() {
|
public synchronized void removeVulnerability(Vulnerability v) {
|
||||||
return projectReferences;
|
this.vulnerabilities.remove(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value of projectReferences.
|
* Get the unmodifiable set of {@link #relatedDependencies}. This field is
|
||||||
|
* used to collect other dependencies which really represent the same
|
||||||
|
* dependency, and may be presented as one item in reports.
|
||||||
*
|
*
|
||||||
* @param projectReferences new value of projectReferences
|
* @return the unmodifiable set of relatedDependencies
|
||||||
*/
|
*/
|
||||||
public void setProjectReferences(Set<String> projectReferences) {
|
public synchronized Set<Dependency> getRelatedDependencies() {
|
||||||
this.projectReferences = projectReferences;
|
return Collections.unmodifiableSet(new HashSet<>(relatedDependencies));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the unmodifiable set of projectReferences.
|
||||||
|
*
|
||||||
|
* @return the unmodifiable set of projectReferences
|
||||||
|
*/
|
||||||
|
public synchronized Set<String> getProjectReferences() {
|
||||||
|
return Collections.unmodifiableSet(new HashSet<>(projectReferences));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -590,7 +585,7 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
*
|
*
|
||||||
* @param projectReference a project reference
|
* @param projectReference a project reference
|
||||||
*/
|
*/
|
||||||
public void addProjectReference(String projectReference) {
|
public synchronized void addProjectReference(String projectReference) {
|
||||||
this.projectReferences.add(projectReference);
|
this.projectReferences.add(projectReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,19 +594,10 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
*
|
*
|
||||||
* @param projectReferences a set of project references
|
* @param projectReferences a set of project references
|
||||||
*/
|
*/
|
||||||
public void addAllProjectReferences(Set<String> projectReferences) {
|
public synchronized void addAllProjectReferences(Set<String> projectReferences) {
|
||||||
this.projectReferences.addAll(projectReferences);
|
this.projectReferences.addAll(projectReferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value of relatedDependencies.
|
|
||||||
*
|
|
||||||
* @param relatedDependencies new value of relatedDependencies
|
|
||||||
*/
|
|
||||||
public void setRelatedDependencies(Set<Dependency> relatedDependencies) {
|
|
||||||
this.relatedDependencies = relatedDependencies;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a related dependency. The internal collection is normally a
|
* Adds a related dependency. The internal collection is normally a
|
||||||
* {@link java.util.TreeSet}, which relies on
|
* {@link java.util.TreeSet}, which relies on
|
||||||
@@ -621,7 +607,7 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
*
|
*
|
||||||
* @param dependency a reference to the related dependency
|
* @param dependency a reference to the related dependency
|
||||||
*/
|
*/
|
||||||
public void addRelatedDependency(Dependency dependency) {
|
public synchronized void addRelatedDependency(Dependency dependency) {
|
||||||
if (this == dependency) {
|
if (this == dependency) {
|
||||||
LOGGER.warn("Attempted to add a circular reference - please post the log file to issue #172 here "
|
LOGGER.warn("Attempted to add a circular reference - please post the log file to issue #172 here "
|
||||||
+ "https://github.com/jeremylong/DependencyCheck/issues/172");
|
+ "https://github.com/jeremylong/DependencyCheck/issues/172");
|
||||||
@@ -634,22 +620,22 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a related dependency.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency to remove
|
||||||
|
*/
|
||||||
|
public synchronized void removeRelatedDependencies(Dependency dependency) {
|
||||||
|
this.relatedDependencies.remove(dependency);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of availableVersions.
|
* Get the value of availableVersions.
|
||||||
*
|
*
|
||||||
* @return the value of availableVersions
|
* @return the value of availableVersions
|
||||||
*/
|
*/
|
||||||
public List<String> getAvailableVersions() {
|
public synchronized List<String> getAvailableVersions() {
|
||||||
return availableVersions;
|
return Collections.unmodifiableList(new ArrayList<>(availableVersions));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value of availableVersions.
|
|
||||||
*
|
|
||||||
* @param availableVersions new value of availableVersions
|
|
||||||
*/
|
|
||||||
public void setAvailableVersions(List<String> availableVersions) {
|
|
||||||
this.availableVersions = availableVersions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -657,7 +643,7 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
*
|
*
|
||||||
* @param version the version to add to the list
|
* @param version the version to add to the list
|
||||||
*/
|
*/
|
||||||
public void addAvailableVersion(String version) {
|
public synchronized void addAvailableVersion(String version) {
|
||||||
this.availableVersions.add(version);
|
this.availableVersions.add(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -746,4 +732,13 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath
|
return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath
|
||||||
+ "', filePath='" + filePath + "', packagePath='" + packagePath + "'}";
|
+ "', filePath='" + filePath + "', packagePath='" + packagePath + "'}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a list of suppressed vulnerabilities to the collection.
|
||||||
|
*
|
||||||
|
* @param vulns the list of suppressed vulnerabilities to add
|
||||||
|
*/
|
||||||
|
public synchronized void addSuppressedVulnerabilities(List<Vulnerability> vulns) {
|
||||||
|
this.suppressedVulnerabilities.addAll(vulns);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,13 +119,13 @@ class EvidenceCollection implements Serializable {
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case VENDOR:
|
case VENDOR:
|
||||||
list = Collections.unmodifiableSet(vendors);
|
list = Collections.unmodifiableSet(new HashSet<>(vendors));
|
||||||
break;
|
break;
|
||||||
case PRODUCT:
|
case PRODUCT:
|
||||||
list = Collections.unmodifiableSet(products);
|
list = Collections.unmodifiableSet(new HashSet<>(products));
|
||||||
break;
|
break;
|
||||||
case VERSION:
|
case VERSION:
|
||||||
list = Collections.unmodifiableSet(versions);
|
list = Collections.unmodifiableSet(new HashSet<>(versions));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
@@ -254,7 +254,7 @@ class EvidenceCollection implements Serializable {
|
|||||||
* @return an unmodifiable set of vendor weighting strings
|
* @return an unmodifiable set of vendor weighting strings
|
||||||
*/
|
*/
|
||||||
public synchronized Set<String> getVendorWeightings() {
|
public synchronized Set<String> getVendorWeightings() {
|
||||||
return Collections.unmodifiableSet(vendorWeightings);
|
return Collections.unmodifiableSet(new HashSet<>(vendorWeightings));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -265,7 +265,7 @@ class EvidenceCollection implements Serializable {
|
|||||||
* @return an unmodifiable set of vendor weighting strings
|
* @return an unmodifiable set of vendor weighting strings
|
||||||
*/
|
*/
|
||||||
public synchronized Set<String> getProductWeightings() {
|
public synchronized Set<String> getProductWeightings() {
|
||||||
return Collections.unmodifiableSet(productWeightings);
|
return Collections.unmodifiableSet(new HashSet<>(productWeightings));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -278,11 +278,11 @@ class EvidenceCollection implements Serializable {
|
|||||||
if (null != type) {
|
if (null != type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case VENDOR:
|
case VENDOR:
|
||||||
return Collections.unmodifiableSet(vendors);
|
return Collections.unmodifiableSet(new HashSet<>(vendors));
|
||||||
case PRODUCT:
|
case PRODUCT:
|
||||||
return Collections.unmodifiableSet(products);
|
return Collections.unmodifiableSet(new HashSet<>(products));
|
||||||
case VERSION:
|
case VERSION:
|
||||||
return Collections.unmodifiableSet(versions);
|
return Collections.unmodifiableSet(new HashSet<>(versions));
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -278,6 +278,8 @@ public class Vulnerability implements Serializable, Comparable<Vulnerability> {
|
|||||||
* @param vulnSoftware the vulnerable software
|
* @param vulnSoftware the vulnerable software
|
||||||
*/
|
*/
|
||||||
public void updateVulnerableSoftware(VulnerableSoftware vulnSoftware) {
|
public void updateVulnerableSoftware(VulnerableSoftware vulnSoftware) {
|
||||||
|
//this behavior is because the vuln software being updated may have
|
||||||
|
// a value that is not included in the hash/comparison
|
||||||
if (vulnerableSoftware.contains(vulnSoftware)) {
|
if (vulnerableSoftware.contains(vulnSoftware)) {
|
||||||
vulnerableSoftware.remove(vulnSoftware);
|
vulnerableSoftware.remove(vulnSoftware);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,10 @@
|
|||||||
package org.owasp.dependencycheck.xml.suppression;
|
package org.owasp.dependencycheck.xml.suppression;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.dependency.Identifier;
|
import org.owasp.dependencycheck.dependency.Identifier;
|
||||||
@@ -365,9 +367,8 @@ public class SuppressionRule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.hasCpe()) {
|
if (this.hasCpe()) {
|
||||||
final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
|
Set<Identifier> removalList = new HashSet<>();
|
||||||
while (itr.hasNext()) {
|
for (Identifier i : dependency.getIdentifiers()) {
|
||||||
final Identifier i = itr.next();
|
|
||||||
for (PropertyType c : this.cpe) {
|
for (PropertyType c : this.cpe) {
|
||||||
if (identifierMatches("cpe", c, i)) {
|
if (identifierMatches("cpe", c, i)) {
|
||||||
if (!isBase()) {
|
if (!isBase()) {
|
||||||
@@ -376,19 +377,22 @@ public class SuppressionRule {
|
|||||||
}
|
}
|
||||||
dependency.addSuppressedIdentifier(i);
|
dependency.addSuppressedIdentifier(i);
|
||||||
}
|
}
|
||||||
itr.remove();
|
removalList.add(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (Identifier i : removalList) {
|
||||||
|
dependency.removeIdentifier(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (hasCve() || hasCwe() || hasCvssBelow()) {
|
if (hasCve() || hasCwe() || hasCvssBelow()) {
|
||||||
final Iterator<Vulnerability> itr = dependency.getVulnerabilities().iterator();
|
Set<Vulnerability> removeVulns = new HashSet<>();
|
||||||
while (itr.hasNext()) {
|
for (Vulnerability v : dependency.getVulnerabilities()) {
|
||||||
boolean remove = false;
|
boolean remove = false;
|
||||||
final Vulnerability v = itr.next();
|
|
||||||
for (String entry : this.cve) {
|
for (String entry : this.cve) {
|
||||||
if (entry.equalsIgnoreCase(v.getName())) {
|
if (entry.equalsIgnoreCase(v.getName())) {
|
||||||
|
removeVulns.add(v);
|
||||||
remove = true;
|
remove = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -400,6 +404,7 @@ public class SuppressionRule {
|
|||||||
final String toTest = v.getCwe().substring(0, toMatch.length()).toUpperCase();
|
final String toTest = v.getCwe().substring(0, toMatch.length()).toUpperCase();
|
||||||
if (toTest.equals(toMatch)) {
|
if (toTest.equals(toMatch)) {
|
||||||
remove = true;
|
remove = true;
|
||||||
|
removeVulns.add(v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -409,6 +414,7 @@ public class SuppressionRule {
|
|||||||
for (float cvss : this.cvssBelow) {
|
for (float cvss : this.cvssBelow) {
|
||||||
if (v.getCvssScore() < cvss) {
|
if (v.getCvssScore() < cvss) {
|
||||||
remove = true;
|
remove = true;
|
||||||
|
removeVulns.add(v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -420,9 +426,11 @@ public class SuppressionRule {
|
|||||||
}
|
}
|
||||||
dependency.addSuppressedVulnerability(v);
|
dependency.addSuppressedVulnerability(v);
|
||||||
}
|
}
|
||||||
itr.remove();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (Vulnerability v : removeVulns) {
|
||||||
|
dependency.removeVulnerability(v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ public class DependencyTest extends BaseTest {
|
|||||||
public void testSetIdentifiers() {
|
public void testSetIdentifiers() {
|
||||||
Set<Identifier> identifiers = new HashSet<>();
|
Set<Identifier> identifiers = new HashSet<>();
|
||||||
Dependency instance = new Dependency();
|
Dependency instance = new Dependency();
|
||||||
instance.setIdentifiers(identifiers);
|
instance.addIdentifiers(identifiers);
|
||||||
assertNotNull(instance.getIdentifiers());
|
assertNotNull(instance.getIdentifiers());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,7 +220,7 @@ public class DependencyTest extends BaseTest {
|
|||||||
MavenArtifact mavenArtifact = new MavenArtifact("group", "artifact", "version", "url");
|
MavenArtifact mavenArtifact = new MavenArtifact("group", "artifact", "version", "url");
|
||||||
instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH);
|
instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH);
|
||||||
assertTrue(instance.contains(EvidenceType.VENDOR, Confidence.HIGH));
|
assertTrue(instance.contains(EvidenceType.VENDOR, Confidence.HIGH));
|
||||||
assertTrue(instance.size()>1);
|
assertTrue(instance.size() > 1);
|
||||||
assertFalse(instance.getIdentifiers().isEmpty());
|
assertFalse(instance.getIdentifiers().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ public class DependencyTest extends BaseTest {
|
|||||||
MavenArtifact mavenArtifact = new MavenArtifact(null, null, null, null);
|
MavenArtifact mavenArtifact = new MavenArtifact(null, null, null, null);
|
||||||
instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH);
|
instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH);
|
||||||
assertFalse(instance.getEvidence(EvidenceType.VENDOR).contains(Confidence.HIGH));
|
assertFalse(instance.getEvidence(EvidenceType.VENDOR).contains(Confidence.HIGH));
|
||||||
assertTrue(instance.size()==0);
|
assertTrue(instance.size() == 0);
|
||||||
assertTrue(instance.getIdentifiers().isEmpty());
|
assertTrue(instance.getIdentifiers().isEmpty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user