mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-01-14 15:53:36 +01:00
Compare commits
75 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
848be0db6c | ||
|
|
0f9da0731e | ||
|
|
8bc2364cce | ||
|
|
b64916ce3f | ||
|
|
452955667c | ||
|
|
f38bbf4cc7 | ||
|
|
25eaa11a52 | ||
|
|
4b4da8d467 | ||
|
|
13116c5381 | ||
|
|
d2cd406a62 | ||
|
|
acbce05fbf | ||
|
|
bee4d3a338 | ||
|
|
bce226002b | ||
|
|
a417db7c7a | ||
|
|
0ffef12a8b | ||
|
|
4539b040e0 | ||
|
|
f85014a86d | ||
|
|
d90d07c68b | ||
|
|
ce292b84fa | ||
|
|
01690860db | ||
|
|
89fb2d4915 | ||
|
|
5cc3a42832 | ||
|
|
60b0145e04 | ||
|
|
ce48823d38 | ||
|
|
d43fee5585 | ||
|
|
5dc9e51dd4 | ||
|
|
235fcccbd7 | ||
|
|
91c971b8fd | ||
|
|
e43003cadc | ||
|
|
9a96165655 | ||
|
|
994aef411c | ||
|
|
094a180935 | ||
|
|
74e9de6370 | ||
|
|
c7f31b3d79 | ||
|
|
98d0239d03 | ||
|
|
ffeab147ce | ||
|
|
90bdbd6b84 | ||
|
|
e29dd3cd33 | ||
|
|
23b95178ff | ||
|
|
9bde80357f | ||
|
|
1485733715 | ||
|
|
d125a7f09d | ||
|
|
77486dffd4 | ||
|
|
c84bcb433f | ||
|
|
f1e5221257 | ||
|
|
b8bf01acc3 | ||
|
|
65aa7bd1de | ||
|
|
6f511444a7 | ||
|
|
ef5174d89f | ||
|
|
e2a97e75d8 | ||
|
|
9fc6e265eb | ||
|
|
f81c42b1fd | ||
|
|
8594e146eb | ||
|
|
cda0dfdafe | ||
|
|
363568b02c | ||
|
|
443ab02788 | ||
|
|
65784d6dc4 | ||
|
|
da805d037f | ||
|
|
d383776245 | ||
|
|
51eba8da73 | ||
|
|
14b4d64244 | ||
|
|
7cb7f68cda | ||
|
|
83300d028b | ||
|
|
e891ce39c0 | ||
|
|
e58b7782ac | ||
|
|
1ddb468a08 | ||
|
|
95e3f0e0d9 | ||
|
|
0edf017ddc | ||
|
|
ad601fd1ee | ||
|
|
e7eaccb5e0 | ||
|
|
6b201da3ff | ||
|
|
a85a47bc20 | ||
|
|
0d943ba805 | ||
|
|
56fe3b5892 | ||
|
|
c177f12e1d |
@@ -21,12 +21,10 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.2.0</version>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dependency-check-ant</artifactId>
|
||||
<version>1.2.0.1</version>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Dependency-Check Ant Task</name>
|
||||
@@ -441,6 +439,11 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
||||
<artifactId>dependency-check-core</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-utils</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-core</artifactId>
|
||||
|
||||
@@ -285,26 +285,50 @@ public class DependencyCheckTask extends Task {
|
||||
this.reportFormat = reportFormat.getValue();
|
||||
}
|
||||
/**
|
||||
* The Proxy URL.
|
||||
* The Proxy Server.
|
||||
*/
|
||||
private String proxyUrl;
|
||||
private String proxyServer;
|
||||
|
||||
/**
|
||||
* Get the value of proxyUrl.
|
||||
* Get the value of proxyServer.
|
||||
*
|
||||
* @return the value of proxyUrl
|
||||
* @return the value of proxyServer
|
||||
*/
|
||||
public String getProxyUrl() {
|
||||
return proxyUrl;
|
||||
public String getProxyServer() {
|
||||
return proxyServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of proxyUrl.
|
||||
* Set the value of proxyServer.
|
||||
*
|
||||
* @param proxyUrl new value of proxyUrl
|
||||
* @param server new value of proxyServer
|
||||
*/
|
||||
public void setProxyServer(String server) {
|
||||
this.proxyServer = server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of proxyServer.
|
||||
*
|
||||
* @return the value of proxyServer
|
||||
* @deprecated use {@link org.owasp.dependencycheck.taskdefs.DependencyCheckTask#getProxyServer()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public String getProxyUrl() {
|
||||
return proxyServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of proxyServer.
|
||||
*
|
||||
* @param proxyUrl new value of proxyServer
|
||||
* @deprecated use {@link org.owasp.dependencycheck.taskdefs.DependencyCheckTask#setProxyServer(java.lang.String)}
|
||||
* instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void setProxyUrl(String proxyUrl) {
|
||||
this.proxyUrl = proxyUrl;
|
||||
LOGGER.warning("A deprecated configuration option 'proxyUrl' was detected; use 'proxyServer' instead.");
|
||||
this.proxyServer = proxyUrl;
|
||||
}
|
||||
/**
|
||||
* The Proxy Port.
|
||||
@@ -866,7 +890,7 @@ public class DependencyCheckTask extends Task {
|
||||
|
||||
Engine engine = null;
|
||||
try {
|
||||
engine = new Engine();
|
||||
engine = new Engine(DependencyCheckTask.class.getClassLoader());
|
||||
|
||||
for (Resource resource : path) {
|
||||
final FileProvider provider = resource.as(FileProvider.class);
|
||||
@@ -912,7 +936,7 @@ public class DependencyCheckTask extends Task {
|
||||
LOGGER.log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped");
|
||||
LOGGER.log(Level.FINE, "", ex);
|
||||
} finally {
|
||||
Settings.cleanup();
|
||||
Settings.cleanup(true);
|
||||
if (engine != null) {
|
||||
engine.cleanup();
|
||||
}
|
||||
@@ -935,7 +959,7 @@ public class DependencyCheckTask extends Task {
|
||||
|
||||
/**
|
||||
* Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system
|
||||
* properties required to change the proxy url, port, and connection timeout.
|
||||
* properties required to change the proxy server, port, and connection timeout.
|
||||
*/
|
||||
private void populateSettings() {
|
||||
Settings.initialize();
|
||||
@@ -967,8 +991,8 @@ public class DependencyCheckTask extends Task {
|
||||
|
||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
|
||||
|
||||
if (proxyUrl != null && !proxyUrl.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.PROXY_URL, proxyUrl);
|
||||
if (proxyServer != null && !proxyServer.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.PROXY_SERVER, proxyServer);
|
||||
}
|
||||
if (proxyPort != null && !proxyPort.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort);
|
||||
|
||||
@@ -32,7 +32,7 @@ failBuildOnCVSS | Specifies if the build should be failed if a CVSS score a
|
||||
format | The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the Site plugin unless the externalReport is set to true. | HTML
|
||||
logFile | The file path to write verbose logging information. |
|
||||
suppressionFile | The file path to the XML suppression file \- used to suppress [false positives](../suppression.html) |
|
||||
proxyUrl | The Proxy URL. |
|
||||
proxyServer | The Proxy Server. |
|
||||
proxyPort | The Proxy Port. |
|
||||
proxyUsername | Defines the proxy user name. |
|
||||
proxyPassword | Defines the proxy password. |
|
||||
|
||||
@@ -45,7 +45,7 @@ public class DependencyCheckTaskTest extends BuildFileTest {
|
||||
public void tearDown() {
|
||||
//no cleanup...
|
||||
//executeTarget("cleanup");
|
||||
Settings.cleanup();
|
||||
Settings.cleanup(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,7 +21,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.2.0</version>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dependency-check-cli</artifactId>
|
||||
@@ -341,5 +341,10 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
||||
<artifactId>dependency-check-core</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-utils</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -62,7 +62,7 @@ public class App {
|
||||
final App app = new App();
|
||||
app.run(args);
|
||||
} finally {
|
||||
Settings.cleanup();
|
||||
Settings.cleanup(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ public class App {
|
||||
|
||||
final boolean autoUpdate = cli.isAutoUpdate();
|
||||
final String connectionTimeout = cli.getConnectionTimeout();
|
||||
final String proxyUrl = cli.getProxyUrl();
|
||||
final String proxyServer = cli.getProxyServer();
|
||||
final String proxyPort = cli.getProxyPort();
|
||||
final String proxyUser = cli.getProxyUsername();
|
||||
final String proxyPass = cli.getProxyPassword();
|
||||
@@ -212,8 +212,8 @@ public class App {
|
||||
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
|
||||
}
|
||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
|
||||
if (proxyUrl != null && !proxyUrl.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.PROXY_URL, proxyUrl);
|
||||
if (proxyServer != null && !proxyServer.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.PROXY_SERVER, proxyServer);
|
||||
}
|
||||
if (proxyPort != null && !proxyPort.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort);
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.owasp.dependencycheck.cli;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.logging.Logger;
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
@@ -39,6 +40,10 @@ import org.owasp.dependencycheck.utils.Settings;
|
||||
*/
|
||||
public final class CliParser {
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*/
|
||||
private static final Logger LOGGER = Logger.getLogger(CliParser.class.getName());
|
||||
/**
|
||||
* The command line.
|
||||
*/
|
||||
@@ -85,16 +90,16 @@ public final class CliParser {
|
||||
*/
|
||||
private void validateArgs() throws FileNotFoundException, ParseException {
|
||||
if (isRunScan()) {
|
||||
validatePathExists(getScanFiles(), ArgumentName.SCAN);
|
||||
validatePathExists(getReportDirectory(), ArgumentName.OUT);
|
||||
validatePathExists(getScanFiles(), ARGUMENT.SCAN);
|
||||
validatePathExists(getReportDirectory(), ARGUMENT.OUT);
|
||||
if (getPathToMono() != null) {
|
||||
validatePathExists(getPathToMono(), ArgumentName.PATH_TO_MONO);
|
||||
validatePathExists(getPathToMono(), ARGUMENT.PATH_TO_MONO);
|
||||
}
|
||||
if (!line.hasOption(ArgumentName.APP_NAME)) {
|
||||
if (!line.hasOption(ARGUMENT.APP_NAME)) {
|
||||
throw new ParseException("Missing 'app' argument; the scan cannot be run without the an application name.");
|
||||
}
|
||||
if (line.hasOption(ArgumentName.OUTPUT_FORMAT)) {
|
||||
final String format = line.getOptionValue(ArgumentName.OUTPUT_FORMAT);
|
||||
if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) {
|
||||
final String format = line.getOptionValue(ARGUMENT.OUTPUT_FORMAT);
|
||||
try {
|
||||
Format.valueOf(format);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
@@ -150,7 +155,7 @@ public final class CliParser {
|
||||
final Options options = new Options();
|
||||
addStandardOptions(options);
|
||||
addAdvancedOptions(options);
|
||||
|
||||
addDeprecatedOptions(options);
|
||||
return options;
|
||||
}
|
||||
|
||||
@@ -162,44 +167,44 @@ public final class CliParser {
|
||||
*/
|
||||
@SuppressWarnings("static-access")
|
||||
private void addStandardOptions(final Options options) throws IllegalArgumentException {
|
||||
final Option help = new Option(ArgumentName.HELP_SHORT, ArgumentName.HELP, false,
|
||||
final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false,
|
||||
"Print this message.");
|
||||
|
||||
final Option advancedHelp = OptionBuilder.withLongOpt(ArgumentName.ADVANCED_HELP)
|
||||
final Option advancedHelp = OptionBuilder.withLongOpt(ARGUMENT.ADVANCED_HELP)
|
||||
.withDescription("Print the advanced help message.").create();
|
||||
|
||||
final Option version = new Option(ArgumentName.VERSION_SHORT, ArgumentName.VERSION,
|
||||
final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION,
|
||||
false, "Print the version information.");
|
||||
|
||||
final Option noUpdate = new Option(ArgumentName.DISABLE_AUTO_UPDATE_SHORT, ArgumentName.DISABLE_AUTO_UPDATE,
|
||||
final Option noUpdate = new Option(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE,
|
||||
false, "Disables the automatic updating of the CPE data.");
|
||||
|
||||
final Option appName = OptionBuilder.withArgName("name").hasArg().withLongOpt(ArgumentName.APP_NAME)
|
||||
final Option appName = OptionBuilder.withArgName("name").hasArg().withLongOpt(ARGUMENT.APP_NAME)
|
||||
.withDescription("The name of the application being scanned. This is a required argument.")
|
||||
.create(ArgumentName.APP_NAME_SHORT);
|
||||
.create(ARGUMENT.APP_NAME_SHORT);
|
||||
|
||||
final Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.SCAN)
|
||||
final Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.SCAN)
|
||||
.withDescription("The path to scan - this option can be specified multiple times. To limit the scan"
|
||||
+ " to specific file types *.[ext] can be added to the end of the path.")
|
||||
.create(ArgumentName.SCAN_SHORT);
|
||||
.create(ARGUMENT.SCAN_SHORT);
|
||||
|
||||
final Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.PROP)
|
||||
final Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.PROP)
|
||||
.withDescription("A property file to load.")
|
||||
.create(ArgumentName.PROP_SHORT);
|
||||
.create(ARGUMENT.PROP_SHORT);
|
||||
|
||||
final Option out = OptionBuilder.withArgName("folder").hasArg().withLongOpt(ArgumentName.OUT)
|
||||
final Option out = OptionBuilder.withArgName("folder").hasArg().withLongOpt(ARGUMENT.OUT)
|
||||
.withDescription("The folder to write reports to. This defaults to the current directory.")
|
||||
.create(ArgumentName.OUT_SHORT);
|
||||
.create(ARGUMENT.OUT_SHORT);
|
||||
|
||||
final Option outputFormat = OptionBuilder.withArgName("format").hasArg().withLongOpt(ArgumentName.OUTPUT_FORMAT)
|
||||
final Option outputFormat = OptionBuilder.withArgName("format").hasArg().withLongOpt(ARGUMENT.OUTPUT_FORMAT)
|
||||
.withDescription("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.")
|
||||
.create(ArgumentName.OUTPUT_FORMAT_SHORT);
|
||||
.create(ARGUMENT.OUTPUT_FORMAT_SHORT);
|
||||
|
||||
final Option verboseLog = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.VERBOSE_LOG)
|
||||
final Option verboseLog = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.VERBOSE_LOG)
|
||||
.withDescription("The file path to write verbose logging information.")
|
||||
.create(ArgumentName.VERBOSE_LOG_SHORT);
|
||||
.create(ARGUMENT.VERBOSE_LOG_SHORT);
|
||||
|
||||
final Option suppressionFile = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.SUPPRESSION_FILE)
|
||||
final Option suppressionFile = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.SUPPRESSION_FILE)
|
||||
.withDescription("The file path to the suppression XML file.")
|
||||
.create();
|
||||
|
||||
@@ -230,87 +235,87 @@ public final class CliParser {
|
||||
@SuppressWarnings("static-access")
|
||||
private void addAdvancedOptions(final Options options) throws IllegalArgumentException {
|
||||
|
||||
final Option data = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.DATA_DIRECTORY)
|
||||
final Option data = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.DATA_DIRECTORY)
|
||||
.withDescription("The location of the H2 Database file. This option should generally not be set.")
|
||||
.create(ArgumentName.DATA_DIRECTORY_SHORT);
|
||||
.create(ARGUMENT.DATA_DIRECTORY_SHORT);
|
||||
|
||||
final Option connectionTimeout = OptionBuilder.withArgName("timeout").hasArg().withLongOpt(ArgumentName.CONNECTION_TIMEOUT)
|
||||
final Option connectionTimeout = OptionBuilder.withArgName("timeout").hasArg().withLongOpt(ARGUMENT.CONNECTION_TIMEOUT)
|
||||
.withDescription("The connection timeout (in milliseconds) to use when downloading resources.")
|
||||
.create(ArgumentName.CONNECTION_TIMEOUT_SHORT);
|
||||
.create(ARGUMENT.CONNECTION_TIMEOUT_SHORT);
|
||||
|
||||
final Option proxyUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ArgumentName.PROXY_URL)
|
||||
.withDescription("The proxy url to use when downloading resources.")
|
||||
.create(ArgumentName.PROXY_URL_SHORT);
|
||||
final Option proxyServer = OptionBuilder.withArgName("server").hasArg().withLongOpt(ARGUMENT.PROXY_SERVER)
|
||||
.withDescription("The proxy server to use when downloading resources.")
|
||||
.create();
|
||||
|
||||
final Option proxyPort = OptionBuilder.withArgName("port").hasArg().withLongOpt(ArgumentName.PROXY_PORT)
|
||||
final Option proxyPort = OptionBuilder.withArgName("port").hasArg().withLongOpt(ARGUMENT.PROXY_PORT)
|
||||
.withDescription("The proxy port to use when downloading resources.")
|
||||
.create(ArgumentName.PROXY_PORT_SHORT);
|
||||
.create();
|
||||
|
||||
final Option proxyUsername = OptionBuilder.withArgName("user").hasArg().withLongOpt(ArgumentName.PROXY_USERNAME)
|
||||
final Option proxyUsername = OptionBuilder.withArgName("user").hasArg().withLongOpt(ARGUMENT.PROXY_USERNAME)
|
||||
.withDescription("The proxy username to use when downloading resources.")
|
||||
.create();
|
||||
|
||||
final Option proxyPassword = OptionBuilder.withArgName("pass").hasArg().withLongOpt(ArgumentName.PROXY_PASSWORD)
|
||||
final Option proxyPassword = OptionBuilder.withArgName("pass").hasArg().withLongOpt(ARGUMENT.PROXY_PASSWORD)
|
||||
.withDescription("The proxy password to use when downloading resources.")
|
||||
.create();
|
||||
|
||||
final Option connectionString = OptionBuilder.withArgName("connStr").hasArg().withLongOpt(ArgumentName.CONNECTION_STRING)
|
||||
final Option connectionString = OptionBuilder.withArgName("connStr").hasArg().withLongOpt(ARGUMENT.CONNECTION_STRING)
|
||||
.withDescription("The connection string to the database.")
|
||||
.create();
|
||||
|
||||
final Option dbUser = OptionBuilder.withArgName("user").hasArg().withLongOpt(ArgumentName.DB_NAME)
|
||||
final Option dbUser = OptionBuilder.withArgName("user").hasArg().withLongOpt(ARGUMENT.DB_NAME)
|
||||
.withDescription("The username used to connect to the database.")
|
||||
.create();
|
||||
|
||||
final Option dbPassword = OptionBuilder.withArgName("password").hasArg().withLongOpt(ArgumentName.DB_PASSWORD)
|
||||
final Option dbPassword = OptionBuilder.withArgName("password").hasArg().withLongOpt(ARGUMENT.DB_PASSWORD)
|
||||
.withDescription("The password for connecting to the database.")
|
||||
.create();
|
||||
|
||||
final Option dbDriver = OptionBuilder.withArgName("driver").hasArg().withLongOpt(ArgumentName.DB_DRIVER)
|
||||
final Option dbDriver = OptionBuilder.withArgName("driver").hasArg().withLongOpt(ARGUMENT.DB_DRIVER)
|
||||
.withDescription("The database driver name.")
|
||||
.create();
|
||||
|
||||
final Option dbDriverPath = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.DB_DRIVER_PATH)
|
||||
final Option dbDriverPath = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.DB_DRIVER_PATH)
|
||||
.withDescription("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.")
|
||||
.create();
|
||||
|
||||
final Option disableJarAnalyzer = OptionBuilder.withLongOpt(ArgumentName.DISABLE_JAR)
|
||||
final Option disableJarAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_JAR)
|
||||
.withDescription("Disable the Jar Analyzer.")
|
||||
.create();
|
||||
final Option disableArchiveAnalyzer = OptionBuilder.withLongOpt(ArgumentName.DISABLE_ARCHIVE)
|
||||
final Option disableArchiveAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_ARCHIVE)
|
||||
.withDescription("Disable the Archive Analyzer.")
|
||||
.create();
|
||||
final Option disableNuspecAnalyzer = OptionBuilder.withLongOpt(ArgumentName.DISABLE_NUSPEC)
|
||||
final Option disableNuspecAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_NUSPEC)
|
||||
.withDescription("Disable the Nuspec Analyzer.")
|
||||
.create();
|
||||
final Option disableAssemblyAnalyzer = OptionBuilder.withLongOpt(ArgumentName.DISABLE_ASSEMBLY)
|
||||
final Option disableAssemblyAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_ASSEMBLY)
|
||||
.withDescription("Disable the .NET Assembly Analyzer.")
|
||||
.create();
|
||||
|
||||
final Option disableNexusAnalyzer = OptionBuilder.withLongOpt(ArgumentName.DISABLE_NEXUS)
|
||||
final Option disableNexusAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_NEXUS)
|
||||
.withDescription("Disable the Nexus Analyzer.")
|
||||
.create();
|
||||
|
||||
final Option nexusUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ArgumentName.NEXUS_URL)
|
||||
final Option nexusUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.NEXUS_URL)
|
||||
.withDescription("The url to the Nexus Server.")
|
||||
.create();
|
||||
|
||||
final Option nexusUsesProxy = OptionBuilder.withArgName("true/false").hasArg().withLongOpt(ArgumentName.NEXUS_USES_PROXY)
|
||||
final Option nexusUsesProxy = OptionBuilder.withArgName("true/false").hasArg().withLongOpt(ARGUMENT.NEXUS_USES_PROXY)
|
||||
.withDescription("Whether or not the configured proxy should be used when connecting to Nexus.")
|
||||
.create();
|
||||
|
||||
final Option additionalZipExtensions = OptionBuilder.withArgName("extensions").hasArg()
|
||||
.withLongOpt(ArgumentName.ADDITIONAL_ZIP_EXTENSIONS)
|
||||
.withLongOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS)
|
||||
.withDescription("A comma separated list of additional extensions to be scanned as ZIP files "
|
||||
+ "(ZIP, EAR, WAR are already treated as zip files)")
|
||||
.create();
|
||||
|
||||
final Option pathToMono = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.PATH_TO_MONO)
|
||||
final Option pathToMono = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.PATH_TO_MONO)
|
||||
.withDescription("The path to Mono for .NET Assembly analysis on non-windows systems.")
|
||||
.create();
|
||||
|
||||
options.addOption(proxyPort)
|
||||
.addOption(proxyUrl)
|
||||
.addOption(proxyServer)
|
||||
.addOption(proxyUsername)
|
||||
.addOption(proxyPassword)
|
||||
.addOption(connectionTimeout)
|
||||
@@ -331,13 +336,30 @@ public final class CliParser {
|
||||
.addOption(pathToMono);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the deprecated command line options to the given options collection. These are split out for purposes of not
|
||||
* including them in the help message. We need to add the deprecated options so as not to break existing scripts.
|
||||
*
|
||||
* @param options a collection of command line arguments
|
||||
* @throws IllegalArgumentException thrown if there is an exception
|
||||
*/
|
||||
@SuppressWarnings("static-access")
|
||||
private void addDeprecatedOptions(final Options options) throws IllegalArgumentException {
|
||||
|
||||
final Option proxyServer = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.PROXY_URL)
|
||||
.withDescription("The proxy url argument is deprecated, use proxyserver instead.")
|
||||
.create();
|
||||
|
||||
options.addOption(proxyServer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the 'version' command line argument was passed in.
|
||||
*
|
||||
* @return whether or not the 'version' command line argument was passed in
|
||||
*/
|
||||
public boolean isGetVersion() {
|
||||
return (line != null) && line.hasOption(ArgumentName.VERSION);
|
||||
return (line != null) && line.hasOption(ARGUMENT.VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -346,7 +368,7 @@ public final class CliParser {
|
||||
* @return whether or not the 'help' command line argument was passed in
|
||||
*/
|
||||
public boolean isGetHelp() {
|
||||
return (line != null) && line.hasOption(ArgumentName.HELP);
|
||||
return (line != null) && line.hasOption(ARGUMENT.HELP);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -355,7 +377,7 @@ public final class CliParser {
|
||||
* @return whether or not the 'scan' command line argument was passed in
|
||||
*/
|
||||
public boolean isRunScan() {
|
||||
return (line != null) && isValid && line.hasOption(ArgumentName.SCAN);
|
||||
return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -364,7 +386,7 @@ public final class CliParser {
|
||||
* @return true if the disableJar command line argument was specified; otherwise false
|
||||
*/
|
||||
public boolean isJarDisabled() {
|
||||
return (line != null) && line.hasOption(ArgumentName.DISABLE_JAR);
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -373,7 +395,7 @@ public final class CliParser {
|
||||
* @return true if the disableArchive command line argument was specified; otherwise false
|
||||
*/
|
||||
public boolean isArchiveDisabled() {
|
||||
return (line != null) && line.hasOption(ArgumentName.DISABLE_ARCHIVE);
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -382,7 +404,7 @@ public final class CliParser {
|
||||
* @return true if the disableNuspec command line argument was specified; otherwise false
|
||||
*/
|
||||
public boolean isNuspecDisabled() {
|
||||
return (line != null) && line.hasOption(ArgumentName.DISABLE_NUSPEC);
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -391,7 +413,7 @@ public final class CliParser {
|
||||
* @return true if the disableAssembly command line argument was specified; otherwise false
|
||||
*/
|
||||
public boolean isAssemblyDisabled() {
|
||||
return (line != null) && line.hasOption(ArgumentName.DISABLE_ASSEMBLY);
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -400,7 +422,7 @@ public final class CliParser {
|
||||
* @return true if the disableNexus command line argument was specified; otherwise false
|
||||
*/
|
||||
public boolean isNexusDisabled() {
|
||||
return (line != null) && line.hasOption(ArgumentName.DISABLE_NEXUS);
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -409,10 +431,10 @@ public final class CliParser {
|
||||
* @return the url to the nexus server; if none was specified this will return null;
|
||||
*/
|
||||
public String getNexusUrl() {
|
||||
if (line == null || !line.hasOption(ArgumentName.NEXUS_URL)) {
|
||||
if (line == null || !line.hasOption(ARGUMENT.NEXUS_URL)) {
|
||||
return null;
|
||||
} else {
|
||||
return line.getOptionValue(ArgumentName.NEXUS_URL);
|
||||
return line.getOptionValue(ARGUMENT.NEXUS_URL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,14 +447,14 @@ public final class CliParser {
|
||||
public boolean isNexusUsesProxy() {
|
||||
// If they didn't specify whether Nexus needs to use the proxy, we should
|
||||
// still honor the property if it's set.
|
||||
if (line == null || !line.hasOption(ArgumentName.NEXUS_USES_PROXY)) {
|
||||
if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) {
|
||||
try {
|
||||
return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY);
|
||||
} catch (InvalidSettingException ise) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return Boolean.parseBoolean(line.getOptionValue(ArgumentName.NEXUS_USES_PROXY));
|
||||
return Boolean.parseBoolean(line.getOptionValue(ARGUMENT.NEXUS_USES_PROXY));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,7 +465,7 @@ public final class CliParser {
|
||||
final HelpFormatter formatter = new HelpFormatter();
|
||||
final Options options = new Options();
|
||||
addStandardOptions(options);
|
||||
if (line != null && line.hasOption(ArgumentName.ADVANCED_HELP)) {
|
||||
if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) {
|
||||
addAdvancedOptions(options);
|
||||
}
|
||||
final String helpMsg = String.format("%n%s"
|
||||
@@ -466,7 +488,7 @@ public final class CliParser {
|
||||
* @return the file paths specified on the command line for scan
|
||||
*/
|
||||
public String[] getScanFiles() {
|
||||
return line.getOptionValues(ArgumentName.SCAN);
|
||||
return line.getOptionValues(ARGUMENT.SCAN);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -475,7 +497,7 @@ public final class CliParser {
|
||||
* @return the path to the reports directory.
|
||||
*/
|
||||
public String getReportDirectory() {
|
||||
return line.getOptionValue(ArgumentName.OUT, ".");
|
||||
return line.getOptionValue(ARGUMENT.OUT, ".");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -484,7 +506,7 @@ public final class CliParser {
|
||||
* @return the path to Mono
|
||||
*/
|
||||
public String getPathToMono() {
|
||||
return line.getOptionValue(ArgumentName.PATH_TO_MONO);
|
||||
return line.getOptionValue(ARGUMENT.PATH_TO_MONO);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -493,7 +515,7 @@ public final class CliParser {
|
||||
* @return the output format name.
|
||||
*/
|
||||
public String getReportFormat() {
|
||||
return line.getOptionValue(ArgumentName.OUTPUT_FORMAT, "HTML");
|
||||
return line.getOptionValue(ARGUMENT.OUTPUT_FORMAT, "HTML");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -502,7 +524,7 @@ public final class CliParser {
|
||||
* @return the application name.
|
||||
*/
|
||||
public String getApplicationName() {
|
||||
return line.getOptionValue(ArgumentName.APP_NAME);
|
||||
return line.getOptionValue(ARGUMENT.APP_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -511,16 +533,24 @@ public final class CliParser {
|
||||
* @return the connection timeout
|
||||
*/
|
||||
public String getConnectionTimeout() {
|
||||
return line.getOptionValue(ArgumentName.CONNECTION_TIMEOUT);
|
||||
return line.getOptionValue(ARGUMENT.CONNECTION_TIMEOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the proxy url.
|
||||
* Returns the proxy server.
|
||||
*
|
||||
* @return the proxy url
|
||||
* @return the proxy server
|
||||
*/
|
||||
public String getProxyUrl() {
|
||||
return line.getOptionValue(ArgumentName.PROXY_URL);
|
||||
public String getProxyServer() {
|
||||
|
||||
String server = line.getOptionValue(ARGUMENT.PROXY_SERVER);
|
||||
if (server == null) {
|
||||
server = line.getOptionValue(ARGUMENT.PROXY_URL);
|
||||
if (server != null) {
|
||||
LOGGER.warning("An old command line argument 'proxyurl' was detected; use proxyserver instead");
|
||||
}
|
||||
}
|
||||
return server;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -529,7 +559,7 @@ public final class CliParser {
|
||||
* @return the proxy port
|
||||
*/
|
||||
public String getProxyPort() {
|
||||
return line.getOptionValue(ArgumentName.PROXY_PORT);
|
||||
return line.getOptionValue(ARGUMENT.PROXY_PORT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -538,7 +568,7 @@ public final class CliParser {
|
||||
* @return the proxy username
|
||||
*/
|
||||
public String getProxyUsername() {
|
||||
return line.getOptionValue(ArgumentName.PROXY_USERNAME);
|
||||
return line.getOptionValue(ARGUMENT.PROXY_USERNAME);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -547,7 +577,7 @@ public final class CliParser {
|
||||
* @return the proxy password
|
||||
*/
|
||||
public String getProxyPassword() {
|
||||
return line.getOptionValue(ArgumentName.PROXY_PASSWORD);
|
||||
return line.getOptionValue(ARGUMENT.PROXY_PASSWORD);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -556,7 +586,7 @@ public final class CliParser {
|
||||
* @return the value of dataDirectory
|
||||
*/
|
||||
public String getDataDirectory() {
|
||||
return line.getOptionValue(ArgumentName.DATA_DIRECTORY);
|
||||
return line.getOptionValue(ARGUMENT.DATA_DIRECTORY);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -565,7 +595,7 @@ public final class CliParser {
|
||||
* @return the properties file specified on the command line
|
||||
*/
|
||||
public File getPropertiesFile() {
|
||||
final String path = line.getOptionValue(ArgumentName.PROP);
|
||||
final String path = line.getOptionValue(ARGUMENT.PROP);
|
||||
if (path != null) {
|
||||
return new File(path);
|
||||
}
|
||||
@@ -578,7 +608,7 @@ public final class CliParser {
|
||||
* @return the path to the verbose log file
|
||||
*/
|
||||
public String getVerboseLog() {
|
||||
return line.getOptionValue(ArgumentName.VERBOSE_LOG);
|
||||
return line.getOptionValue(ARGUMENT.VERBOSE_LOG);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -587,7 +617,7 @@ public final class CliParser {
|
||||
* @return the path to the suppression file
|
||||
*/
|
||||
public String getSuppressionFile() {
|
||||
return line.getOptionValue(ArgumentName.SUPPRESSION_FILE);
|
||||
return line.getOptionValue(ARGUMENT.SUPPRESSION_FILE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -610,7 +640,7 @@ public final class CliParser {
|
||||
* @return if auto-update is allowed.
|
||||
*/
|
||||
public boolean isAutoUpdate() {
|
||||
return (line == null) || !line.hasOption(ArgumentName.DISABLE_AUTO_UPDATE);
|
||||
return (line == null) || !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -619,7 +649,7 @@ public final class CliParser {
|
||||
* @return the database driver name if specified; otherwise null is returned
|
||||
*/
|
||||
public String getDatabaseDriverName() {
|
||||
return line.getOptionValue(ArgumentName.DB_DRIVER);
|
||||
return line.getOptionValue(ARGUMENT.DB_DRIVER);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -628,7 +658,7 @@ public final class CliParser {
|
||||
* @return the database driver name if specified; otherwise null is returned
|
||||
*/
|
||||
public String getDatabaseDriverPath() {
|
||||
return line.getOptionValue(ArgumentName.DB_DRIVER_PATH);
|
||||
return line.getOptionValue(ARGUMENT.DB_DRIVER_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -637,7 +667,7 @@ public final class CliParser {
|
||||
* @return the database connection string if specified; otherwise null is returned
|
||||
*/
|
||||
public String getConnectionString() {
|
||||
return line.getOptionValue(ArgumentName.CONNECTION_STRING);
|
||||
return line.getOptionValue(ARGUMENT.CONNECTION_STRING);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -646,7 +676,7 @@ public final class CliParser {
|
||||
* @return the database database user name if specified; otherwise null is returned
|
||||
*/
|
||||
public String getDatabaseUser() {
|
||||
return line.getOptionValue(ArgumentName.DB_NAME);
|
||||
return line.getOptionValue(ARGUMENT.DB_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -655,7 +685,7 @@ public final class CliParser {
|
||||
* @return the database database password if specified; otherwise null is returned
|
||||
*/
|
||||
public String getDatabasePassword() {
|
||||
return line.getOptionValue(ArgumentName.DB_PASSWORD);
|
||||
return line.getOptionValue(ARGUMENT.DB_PASSWORD);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -664,13 +694,13 @@ public final class CliParser {
|
||||
* @return the additional Extensions; otherwise null is returned
|
||||
*/
|
||||
public String getAdditionalZipExtensions() {
|
||||
return line.getOptionValue(ArgumentName.ADDITIONAL_ZIP_EXTENSIONS);
|
||||
return line.getOptionValue(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* A collection of static final strings that represent the possible command line arguments.
|
||||
*/
|
||||
public static class ArgumentName {
|
||||
public static class ARGUMENT {
|
||||
|
||||
/**
|
||||
* The long CLI argument name specifying the directory/file to scan.
|
||||
@@ -732,21 +762,20 @@ public final class CliParser {
|
||||
* The short CLI argument name asking for the version.
|
||||
*/
|
||||
public static final String VERSION = "version";
|
||||
/**
|
||||
* The short CLI argument name indicating the proxy port.
|
||||
*/
|
||||
public static final String PROXY_PORT_SHORT = "p";
|
||||
/**
|
||||
* The CLI argument name indicating the proxy port.
|
||||
*/
|
||||
public static final String PROXY_PORT = "proxyport";
|
||||
/**
|
||||
* The short CLI argument name indicating the proxy url.
|
||||
* The CLI argument name indicating the proxy server.
|
||||
*/
|
||||
public static final String PROXY_URL_SHORT = "u";
|
||||
public static final String PROXY_SERVER = "proxyserver";
|
||||
/**
|
||||
* The CLI argument name indicating the proxy url.
|
||||
*
|
||||
* @deprecated use {@link org.owasp.dependencycheck.cli.CliParser.ArgumentName#PROXY_SERVER} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String PROXY_URL = "proxyurl";
|
||||
/**
|
||||
* The CLI argument name indicating the proxy username.
|
||||
|
||||
@@ -3,7 +3,7 @@ Command Line Arguments
|
||||
|
||||
The following table lists the command line arguments:
|
||||
|
||||
Short | Argument Name | Parameter | Description | Requirement
|
||||
Short | Argument Name | Parameter | Description | Requirement
|
||||
-------|-----------------------|-----------------|-------------|------------
|
||||
\-a | \-\-app | \<name\> | The name of the application being scanned. This is a required argument. | Required
|
||||
\-s | \-\-scan | \<path\> | The path to scan \- this option can be specified multiple times. It is also possible to specify specific file types that should be scanned by supplying a scan path of '[path]/[to]/[scan]/*.zip'. The wild card can only be used to denote any file-name with a specific extension. | Required
|
||||
@@ -18,7 +18,7 @@ Short | Argument Name | Parameter | Description | Requirement
|
||||
|
||||
Advanced Options
|
||||
================
|
||||
Short | Argument Name | Parameter | Description | Default Value
|
||||
Short | Argument Name | Parameter | Description | Default Value
|
||||
-------|-----------------------|-----------------|-------------|---------------
|
||||
| \-\-disableArchive | | Sets whether the Archive Analyzer will be used. | false
|
||||
| \-\-zipExtensions | \<strings\> | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |
|
||||
@@ -30,7 +30,7 @@ Short | Argument Name | Parameter | Description | Default Value
|
||||
| \-\-disableNuspec | | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | false
|
||||
| \-\-disableAssembly | | Sets whether or not the .NET Assembly Analyzer should be used. | false
|
||||
| \-\-pathToMono | \<path\> | The path to Mono for .NET Assembly analysis on non-windows systems. |
|
||||
| \-\-proxyurl | \<url\> | The proxy url to use when downloading resources. |
|
||||
| \-\-proxyserver | \<server\> | The proxy server to use when downloading resources. |
|
||||
| \-\-proxyport | \<port\> | The proxy port to use when downloading resources. |
|
||||
| \-\-connectiontimeout | \<timeout\> | The connection timeout (in milliseconds) to use when downloading resources. |
|
||||
| \-\-proxypass | \<pass\> | The proxy password to use when downloading resources. |
|
||||
|
||||
@@ -44,7 +44,7 @@ public class CliParserTest {
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownClass() throws Exception {
|
||||
Settings.cleanup();
|
||||
Settings.cleanup(true);
|
||||
}
|
||||
|
||||
@Before
|
||||
|
||||
@@ -15,13 +15,12 @@ limitations under the License.
|
||||
|
||||
Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.2.0</version>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dependency-check-core</artifactId>
|
||||
@@ -220,6 +219,11 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
<name>data.directory</name>
|
||||
<value>${project.build.directory}/data</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>temp.directory</name>
|
||||
<value>${project.build.directory}/temp</value>
|
||||
</property>
|
||||
|
||||
</systemProperties>
|
||||
<includes>
|
||||
<include>**/*IntegrationTest.java</include>
|
||||
@@ -399,6 +403,11 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-utils</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.lucene</groupId>
|
||||
<artifactId>lucene-test-framework</artifactId>
|
||||
@@ -521,6 +530,13 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>3.0.0.RELEASE</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.hazelcast</groupId>
|
||||
<artifactId>hazelcast</artifactId>
|
||||
@@ -662,11 +678,11 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
Additionally, these are only added when using "allTests" to
|
||||
make the build slightly faster in most cases. -->
|
||||
<id>False Positive Tests</id>
|
||||
<!--activation>
|
||||
<activation>
|
||||
<property>
|
||||
<name>allTests</name>
|
||||
</property>
|
||||
</activation-->
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.xmlgraphics</groupId>
|
||||
@@ -689,6 +705,34 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.ganyo</groupId>
|
||||
<artifactId>gcm-server</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.python</groupId>
|
||||
<artifactId>jython-standalone</artifactId>
|
||||
<version>2.7-b1</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jruby</groupId>
|
||||
<artifactId>jruby-complete</artifactId>
|
||||
<version>1.7.4</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jruby</groupId>
|
||||
<artifactId>jruby</artifactId>
|
||||
<version>1.6.3</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||
* Copyright (c) 2014 Steve Springett. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.agent;
|
||||
|
||||
@@ -234,26 +234,49 @@ public class DependencyCheckScanAgent {
|
||||
}
|
||||
|
||||
/**
|
||||
* The Proxy URL.
|
||||
* The Proxy Server.
|
||||
*/
|
||||
private String proxyUrl;
|
||||
private String proxyServer;
|
||||
|
||||
/**
|
||||
* Get the value of proxyUrl.
|
||||
* Get the value of proxyServer.
|
||||
*
|
||||
* @return the value of proxyUrl
|
||||
* @return the value of proxyServer
|
||||
*/
|
||||
public String getProxyUrl() {
|
||||
return proxyUrl;
|
||||
public String getProxyServer() {
|
||||
return proxyServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of proxyUrl.
|
||||
* Set the value of proxyServer.
|
||||
*
|
||||
* @param proxyUrl new value of proxyUrl
|
||||
* @param proxyServer new value of proxyServer
|
||||
*/
|
||||
public void setProxyServer(String proxyServer) {
|
||||
this.proxyServer = proxyServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of proxyServer.
|
||||
*
|
||||
* @return the value of proxyServer
|
||||
* @deprecated use {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#getProxyServer()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public String getProxyUrl() {
|
||||
return proxyServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of proxyServer.
|
||||
*
|
||||
* @param proxyUrl new value of proxyServer
|
||||
* @deprecated use {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#setProxyServer(java.lang.String)
|
||||
* } instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void setProxyUrl(String proxyUrl) {
|
||||
this.proxyUrl = proxyUrl;
|
||||
this.proxyServer = proxyUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -792,7 +815,7 @@ public class DependencyCheckScanAgent {
|
||||
|
||||
/**
|
||||
* Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system
|
||||
* properties required to change the proxy url, port, and connection timeout.
|
||||
* properties required to change the proxy server, port, and connection timeout.
|
||||
*/
|
||||
private void populateSettings() {
|
||||
Settings.initialize();
|
||||
@@ -808,8 +831,8 @@ public class DependencyCheckScanAgent {
|
||||
|
||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
|
||||
|
||||
if (proxyUrl != null && !proxyUrl.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.PROXY_URL, proxyUrl);
|
||||
if (proxyServer != null && !proxyServer.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.PROXY_SERVER, proxyServer);
|
||||
}
|
||||
if (proxyPort != null && !proxyPort.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort);
|
||||
@@ -888,7 +911,7 @@ public class DependencyCheckScanAgent {
|
||||
"Unable to connect to the dependency-check database; analysis has stopped");
|
||||
LOGGER.log(Level.FINE, "", ex);
|
||||
} finally {
|
||||
Settings.cleanup();
|
||||
Settings.cleanup(true);
|
||||
if (engine != null) {
|
||||
engine.cleanup();
|
||||
}
|
||||
|
||||
@@ -98,11 +98,18 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
|
||||
* @throws SuppressionParseException thrown if the XML cannot be parsed.
|
||||
*/
|
||||
private void loadSuppressionData() throws SuppressionParseException {
|
||||
final SuppressionParser parser = new SuppressionParser();
|
||||
File file = null;
|
||||
file = new File(this.getClass().getClassLoader().getResource("dependencycheck-base-suppression.xml").getPath());
|
||||
try {
|
||||
rules = parser.parseSuppressionRules(file);
|
||||
} catch (SuppressionParseException ex) {
|
||||
LOGGER.log(Level.FINE, "Unable to parse the base suppression data file", ex);
|
||||
}
|
||||
final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE);
|
||||
if (suppressionFilePath == null) {
|
||||
return;
|
||||
}
|
||||
File file = null;
|
||||
boolean deleteTempFile = false;
|
||||
try {
|
||||
final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE);
|
||||
@@ -132,9 +139,9 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
|
||||
}
|
||||
|
||||
if (file != null) {
|
||||
final SuppressionParser parser = new SuppressionParser();
|
||||
try {
|
||||
rules = parser.parseSuppressionRules(file);
|
||||
//rules = parser.parseSuppressionRules(file);
|
||||
rules.addAll(parser.parseSuppressionRules(file));
|
||||
LOGGER.log(Level.FINE, rules.size() + " suppression rules were loaded.");
|
||||
} catch (SuppressionParseException ex) {
|
||||
final String msg = String.format("Unable to parse suppression xml file '%s'", file.getPath());
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -35,7 +36,9 @@ import java.util.logging.Logger;
|
||||
import org.apache.commons.compress.archivers.ArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.ArchiveInputStream;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
||||
import org.apache.commons.compress.archivers.zip.ZipFile;
|
||||
import org.apache.commons.compress.compressors.CompressorInputStream;
|
||||
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
|
||||
import org.apache.commons.compress.compressors.gzip.GzipUtils;
|
||||
@@ -99,6 +102,11 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
*/
|
||||
private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz");
|
||||
|
||||
/**
|
||||
* The set of file extensions to remove from the engine's collection of dependencies.
|
||||
*/
|
||||
private static final Set<String> REMOVE_FROM_ANALYSIS = newHashSet("zip", "tar", "gz", "tgz"); //TODO add nupkg, apk, sar?
|
||||
|
||||
static {
|
||||
final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS);
|
||||
if (additionalZipExt != null) {
|
||||
@@ -178,7 +186,7 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
if (tempFileLocation != null && tempFileLocation.exists()) {
|
||||
LOGGER.log(Level.FINE, "Attempting to delete temporary files");
|
||||
final boolean success = FileUtils.delete(tempFileLocation);
|
||||
if (!success) {
|
||||
if (!success && tempFileLocation != null & tempFileLocation.exists()) {
|
||||
LOGGER.log(Level.WARNING, "Failed to delete some temporary files, see the log for more details");
|
||||
}
|
||||
}
|
||||
@@ -199,9 +207,9 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
extractFiles(f, tmpDir, engine);
|
||||
|
||||
//make a copy
|
||||
final List<Dependency> dependencies = new ArrayList<Dependency>(engine.getDependencies());
|
||||
List<Dependency> dependencies = new ArrayList<Dependency>(engine.getDependencies());
|
||||
engine.scan(tmpDir);
|
||||
final List<Dependency> newDependencies = engine.getDependencies();
|
||||
List<Dependency> newDependencies = engine.getDependencies();
|
||||
if (dependencies.size() != newDependencies.size()) {
|
||||
//get the new dependencies
|
||||
final Set<Dependency> dependencySet = new HashSet<Dependency>();
|
||||
@@ -229,6 +237,40 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.REMOVE_FROM_ANALYSIS.contains(dependency.getFileExtension())) {
|
||||
if ("zip".equals(dependency.getFileExtension()) && isZipFileActuallyJarFile(dependency)) {
|
||||
final File tdir = getNextTempDirectory();
|
||||
final String fileName = dependency.getFileName();
|
||||
|
||||
LOGGER.info(String.format("The zip file '%s' appears to be a JAR file, making a deep copy and analyzing it as a JAR.", fileName));
|
||||
|
||||
final File tmpLoc = new File(tdir, fileName.substring(0, fileName.length() - 3) + "jar");
|
||||
try {
|
||||
org.apache.commons.io.FileUtils.copyFile(tdir, tmpLoc);
|
||||
dependencies = new ArrayList<Dependency>(engine.getDependencies());
|
||||
engine.scan(tmpLoc);
|
||||
newDependencies = engine.getDependencies();
|
||||
if (dependencies.size() != newDependencies.size()) {
|
||||
//get the new dependencies
|
||||
final Set<Dependency> dependencySet = new HashSet<Dependency>();
|
||||
dependencySet.addAll(newDependencies);
|
||||
dependencySet.removeAll(dependencies);
|
||||
if (dependencySet.size() != 1) {
|
||||
LOGGER.info("Deep copy of ZIP to JAR file resulted in more then one dependency?");
|
||||
}
|
||||
for (Dependency d : dependencySet) {
|
||||
//fix the dependency's display name and path
|
||||
d.setFilePath(dependency.getFilePath());
|
||||
d.setDisplayFileName(dependency.getFileName());
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
final String msg = String.format("Unable to perform deep copy on '%s'", dependency.getActualFile().getPath());
|
||||
LOGGER.log(Level.FINE, msg, ex);
|
||||
}
|
||||
}
|
||||
engine.getDependencies().remove(dependency);
|
||||
}
|
||||
Collections.sort(engine.getDependencies());
|
||||
}
|
||||
|
||||
@@ -411,4 +453,38 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to determine if a zip file is actually a JAR file.
|
||||
*
|
||||
* @param dependency the dependency to check
|
||||
* @return true if the dependency appears to be a JAR file; otherwise false
|
||||
*/
|
||||
private boolean isZipFileActuallyJarFile(Dependency dependency) {
|
||||
boolean isJar = false;
|
||||
ZipFile zip = null;
|
||||
try {
|
||||
zip = new ZipFile(dependency.getActualFilePath());
|
||||
if (zip.getEntry("META-INF/MANIFEST.MF") != null
|
||||
|| zip.getEntry("META-INF/maven") != null) {
|
||||
final Enumeration<ZipArchiveEntry> entries = zip.getEntries();
|
||||
while (entries.hasMoreElements()) {
|
||||
final ZipArchiveEntry entry = entries.nextElement();
|
||||
if (!entry.isDirectory()) {
|
||||
final String name = entry.getName().toLowerCase();
|
||||
if (name.endsWith(".class")) {
|
||||
isJar = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.FINE, String.format("Unable to unzip zip file '%s'", dependency.getFilePath()), ex);
|
||||
} finally {
|
||||
ZipFile.closeQuietly(zip);
|
||||
}
|
||||
|
||||
return isJar;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
/**
|
||||
* Logger
|
||||
*/
|
||||
private static final Logger LOGGER = Logger.getLogger(AssemblyAnalyzer.class.getName());
|
||||
private static final Logger LOGGER = Logger.getLogger(AssemblyAnalyzer.class.getName(), "dependencycheck-resources");
|
||||
|
||||
/**
|
||||
* Builds the beginnings of a List for ProcessBuilder
|
||||
@@ -106,7 +106,7 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
public void analyzeFileType(Dependency dependency, Engine engine)
|
||||
throws AnalysisException {
|
||||
if (grokAssemblyExe == null) {
|
||||
LOGGER.warning("GrokAssembly didn't get deployed");
|
||||
LOGGER.warning("analyzer.AssemblyAnalyzer.notdeployed");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -114,16 +114,30 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
args.add(dependency.getActualFilePath());
|
||||
final ProcessBuilder pb = new ProcessBuilder(args);
|
||||
BufferedReader rdr = null;
|
||||
Document doc = null;
|
||||
try {
|
||||
final Process proc = pb.start();
|
||||
// Try evacuating the error stream
|
||||
rdr = new BufferedReader(new InputStreamReader(proc.getErrorStream(), "UTF-8"));
|
||||
String line = null;
|
||||
while (rdr.ready() && (line = rdr.readLine()) != null) {
|
||||
LOGGER.log(Level.WARNING, "Error from GrokAssembly: {0}", line);
|
||||
LOGGER.log(Level.WARNING, "analyzer.AssemblyAnalyzer.grokassembly.stderr", line);
|
||||
}
|
||||
int rc = 0;
|
||||
final Document doc = builder.parse(proc.getInputStream());
|
||||
doc = builder.parse(proc.getInputStream());
|
||||
|
||||
try {
|
||||
rc = proc.waitFor();
|
||||
} catch (InterruptedException ie) {
|
||||
return;
|
||||
}
|
||||
if (rc == 3) {
|
||||
LOGGER.log(Level.FINE, "analyzer.AssemblyAnalyzer.notassembly", dependency.getActualFilePath());
|
||||
return;
|
||||
} else if (rc != 0) {
|
||||
LOGGER.log(Level.WARNING, "analyzer.AssemblyAnalyzer.grokassembly.rc", rc);
|
||||
}
|
||||
|
||||
final XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
|
||||
// First, see if there was an error
|
||||
@@ -150,18 +164,6 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
product, Confidence.HIGH));
|
||||
}
|
||||
|
||||
try {
|
||||
rc = proc.waitFor();
|
||||
} catch (InterruptedException ie) {
|
||||
return;
|
||||
}
|
||||
if (rc == 3) {
|
||||
LOGGER.log(Level.INFO, "{0} is not a valid assembly", dependency.getActualFilePath());
|
||||
return;
|
||||
} else if (rc != 0) {
|
||||
LOGGER.log(Level.WARNING, "Return code {0} from GrokAssembly", rc);
|
||||
}
|
||||
|
||||
} catch (IOException ioe) {
|
||||
throw new AnalysisException(ioe);
|
||||
} catch (SAXException saxe) {
|
||||
@@ -201,9 +203,10 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
grokAssemblyExe = tempFile;
|
||||
// Set the temp file to get deleted when we're done
|
||||
grokAssemblyExe.deleteOnExit();
|
||||
LOGGER.log(Level.FINE, "Extracted GrokAssembly.exe to {0}", grokAssemblyExe.getPath());
|
||||
LOGGER.log(Level.FINE, "analyzer.AssemblyAnalyzer.grokassembly.deployed", grokAssemblyExe.getPath());
|
||||
} catch (IOException ioe) {
|
||||
LOGGER.log(Level.WARNING, "Could not extract GrokAssembly.exe: {0}", ioe.getMessage());
|
||||
this.setEnabled(false);
|
||||
LOGGER.log(Level.WARNING, "analyzer.AssemblyAnalyzer.grokassembly.notdeployed", ioe.getMessage());
|
||||
throw new AnalysisException("Could not extract GrokAssembly.exe", ioe);
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
@@ -240,15 +243,16 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
LOGGER.warning("An error occurred with the .NET AssemblyAnalyzer, please see the log for more details.");
|
||||
LOGGER.fine("GrokAssembly.exe is not working properly");
|
||||
grokAssemblyExe = null;
|
||||
this.setEnabled(false);
|
||||
throw new AnalysisException("Could not execute .NET AssemblyAnalyzer");
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof AnalysisException) {
|
||||
throw (AnalysisException) e;
|
||||
} else {
|
||||
LOGGER.warning("An error occured with the .NET AssemblyAnalyzer; "
|
||||
+ "this can be ignored unless you are scanning .NET DLLs. Please see the log for more details.");
|
||||
LOGGER.log(Level.FINE, "Could not execute GrokAssembly {0}", e.getMessage());
|
||||
LOGGER.warning("analyzer.AssemblyAnalyzer.grokassembly.initialization.failed");
|
||||
LOGGER.log(Level.FINE, "analyzer.AssemblyAnalyzer.grokassembly.initialization.message", e.getMessage());
|
||||
this.setEnabled(false);
|
||||
throw new AnalysisException("An error occured with the .NET AssemblyAnalyzer", e);
|
||||
}
|
||||
} finally {
|
||||
@@ -260,7 +264,6 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
}
|
||||
|
||||
@@ -272,7 +275,7 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
grokAssemblyExe.deleteOnExit();
|
||||
}
|
||||
} catch (SecurityException se) {
|
||||
LOGGER.fine("Can't delete temporary GrokAssembly.exe");
|
||||
LOGGER.fine("analyzer.AssemblyAnalyzer.grokassembly.notdeleted");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ import org.owasp.dependencycheck.utils.DependencyVersionUtil;
|
||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||
*/
|
||||
public class CPEAnalyzer implements Analyzer {
|
||||
|
||||
/**
|
||||
* The Logger.
|
||||
*/
|
||||
@@ -90,6 +91,11 @@ public class CPEAnalyzer implements Analyzer {
|
||||
*/
|
||||
private CveDB cve;
|
||||
|
||||
/**
|
||||
* The URL to perform a search of the NVD CVE data at NIST.
|
||||
*/
|
||||
public static final String NVD_SEARCH_URL = "https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=%s";
|
||||
|
||||
/**
|
||||
* Returns the name of this analyzer.
|
||||
*
|
||||
@@ -524,7 +530,8 @@ public class CPEAnalyzer implements Analyzer {
|
||||
}
|
||||
if (dbVer == null //special case, no version specified - everything is vulnerable
|
||||
|| evVer.equals(dbVer)) { //yeah! exact match
|
||||
final String url = String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(vs.getName(), "UTF-8"));
|
||||
|
||||
final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
|
||||
final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf);
|
||||
collected.add(match);
|
||||
} else {
|
||||
@@ -549,7 +556,7 @@ public class CPEAnalyzer implements Analyzer {
|
||||
}
|
||||
}
|
||||
final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString());
|
||||
final String url = null; //String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(cpeName, "UTF-8"));
|
||||
final String url = null;
|
||||
if (bestGuessConf == null) {
|
||||
bestGuessConf = Confidence.LOW;
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
||||
removeBadMatches(dependency);
|
||||
removeWrongVersionMatches(dependency);
|
||||
removeSpuriousCPE(dependency);
|
||||
removeDuplicativeEntriesFromJar(dependency, engine);
|
||||
addFalseNegativeCPEs(dependency);
|
||||
}
|
||||
|
||||
@@ -160,11 +161,20 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
||||
*/
|
||||
public static final Pattern CORE_JAVA = Pattern.compile("^cpe:/a:(sun|oracle|ibm):(j2[ems]e|"
|
||||
+ "java(_platform_micro_edition|_runtime_environment|_se|virtual_machine|se_development_kit|fx)?|"
|
||||
+ "jdk|jre|jsf|jsse)($|:.*)");
|
||||
+ "jdk|jre|jsse)($|:.*)");
|
||||
|
||||
/**
|
||||
* Regex to identify core jsf libraries.
|
||||
*/
|
||||
public static final Pattern CORE_JAVA_JSF = Pattern.compile("^cpe:/a:(sun|oracle|ibm):jsf($|:.*)");
|
||||
/**
|
||||
* Regex to identify core java library files. This is currently incomplete.
|
||||
*/
|
||||
public static final Pattern CORE_FILES = Pattern.compile("^((alt[-])?rt|jsf[-].*|jsse|jfxrt|jfr|jce|javaws|deploy|charsets)\\.jar$");
|
||||
public static final Pattern CORE_FILES = Pattern.compile("(^|/)((alt[-])?rt|jsse|jfxrt|jfr|jce|javaws|deploy|charsets)\\.jar$");
|
||||
/**
|
||||
* Regex to identify core jsf java library files. This is currently incomplete.
|
||||
*/
|
||||
public static final Pattern CORE_JSF_FILES = Pattern.compile("(^|/)jsf[-][^/]*\\.jar$");
|
||||
|
||||
/**
|
||||
* Removes any CPE entries for the JDK/JRE unless the filename ends with rt.jar
|
||||
@@ -181,27 +191,11 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
||||
if (coreCPE.matches() && !coreFiles.matches()) {
|
||||
itr.remove();
|
||||
}
|
||||
|
||||
//replaced with the regex above.
|
||||
// if (("cpe:/a:sun:java".equals(i.getValue())
|
||||
// || "cpe:/a:oracle:java".equals(i.getValue())
|
||||
// || "cpe:/a:ibm:java".equals(i.getValue())
|
||||
// || "cpe:/a:sun:j2se".equals(i.getValue())
|
||||
// || "cpe:/a:oracle:j2se".equals(i.getValue())
|
||||
// || i.getValue().startsWith("cpe:/a:sun:java:")
|
||||
// || i.getValue().startsWith("cpe:/a:sun:j2se:")
|
||||
// || i.getValue().startsWith("cpe:/a:sun:java:jre")
|
||||
// || i.getValue().startsWith("cpe:/a:sun:java:jdk")
|
||||
// || i.getValue().startsWith("cpe:/a:sun:java_se")
|
||||
// || i.getValue().startsWith("cpe:/a:oracle:java_se")
|
||||
// || i.getValue().startsWith("cpe:/a:oracle:java:")
|
||||
// || i.getValue().startsWith("cpe:/a:oracle:j2se:")
|
||||
// || i.getValue().startsWith("cpe:/a:oracle:jre")
|
||||
// || i.getValue().startsWith("cpe:/a:oracle:jdk")
|
||||
// || i.getValue().startsWith("cpe:/a:ibm:java:"))
|
||||
// && !dependency.getFileName().toLowerCase().endsWith("rt.jar")) {
|
||||
// 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()) {
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,14 +242,33 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
||||
//TODO move this startsWith expression to a configuration file?
|
||||
if ("cpe".equals(i.getType())) {
|
||||
if ((i.getValue().matches(".*c\\+\\+.*")
|
||||
|| i.getValue().startsWith("cpe:/a:jquery:jquery")
|
||||
|| i.getValue().startsWith("cpe:/a:prototypejs:prototype")
|
||||
|| i.getValue().startsWith("cpe:/a:yahoo:yui")
|
||||
|| i.getValue().startsWith("cpe:/a:file:file")
|
||||
|| i.getValue().startsWith("cpe:/a:mozilla:mozilla")
|
||||
|| i.getValue().startsWith("cpe:/a:cvs:cvs")
|
||||
|| i.getValue().startsWith("cpe:/a:ftp:ftp")
|
||||
|| i.getValue().startsWith("cpe:/a:ssh:ssh"))
|
||||
|| i.getValue().startsWith("cpe:/a:tcp:tcp")
|
||||
|| i.getValue().startsWith("cpe:/a:ssh:ssh")
|
||||
|| i.getValue().startsWith("cpe:/a:lookup:lookup"))
|
||||
&& (dependency.getFileName().toLowerCase().endsWith(".jar")
|
||||
|| dependency.getFileName().toLowerCase().endsWith("pom.xml")
|
||||
|| dependency.getFileName().toLowerCase().endsWith(".dll")
|
||||
|| dependency.getFileName().toLowerCase().endsWith(".exe")
|
||||
|| dependency.getFileName().toLowerCase().endsWith(".nuspec")
|
||||
|| dependency.getFileName().toLowerCase().endsWith(".nupkg"))) {
|
||||
itr.remove();
|
||||
} else if ((i.getValue().startsWith("cpe:/a:jquery:jquery")
|
||||
|| i.getValue().startsWith("cpe:/a:prototypejs:prototype")
|
||||
|| i.getValue().startsWith("cpe:/a:yahoo:yui"))
|
||||
&& (dependency.getFileName().toLowerCase().endsWith(".jar")
|
||||
|| dependency.getFileName().toLowerCase().endsWith("pom.xml")
|
||||
|| dependency.getFileName().toLowerCase().endsWith(".dll")
|
||||
|| dependency.getFileName().toLowerCase().endsWith(".exe"))) {
|
||||
itr.remove();
|
||||
} else if ((i.getValue().startsWith("cpe:/a:microsoft:excel")
|
||||
|| i.getValue().startsWith("cpe:/a:microsoft:word")
|
||||
|| i.getValue().startsWith("cpe:/a:microsoft:visio")
|
||||
|| i.getValue().startsWith("cpe:/a:microsoft:powerpoint")
|
||||
|| i.getValue().startsWith("cpe:/a:microsoft:office"))
|
||||
&& (dependency.getFileName().toLowerCase().endsWith(".jar")
|
||||
|| dependency.getFileName().toLowerCase().endsWith("pom.xml"))) {
|
||||
itr.remove();
|
||||
@@ -266,7 +279,7 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
||||
&& !dependency.getEvidenceUsed().containsUsedString("m-core")) {
|
||||
itr.remove();
|
||||
} 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();
|
||||
}
|
||||
}
|
||||
@@ -314,6 +327,7 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
||||
* @param dependency the dependency being analyzed
|
||||
*/
|
||||
private void addFalseNegativeCPEs(Dependency dependency) {
|
||||
//TODO move this to the hint analyzer
|
||||
final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
|
||||
while (itr.hasNext()) {
|
||||
final Identifier i = itr.next();
|
||||
@@ -329,20 +343,92 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
||||
try {
|
||||
dependency.addIdentifier("cpe",
|
||||
newCpe,
|
||||
String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(newCpe, "UTF-8")));
|
||||
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe, "UTF-8")));
|
||||
dependency.addIdentifier("cpe",
|
||||
newCpe2,
|
||||
String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(newCpe2, "UTF-8")));
|
||||
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe2, "UTF-8")));
|
||||
dependency.addIdentifier("cpe",
|
||||
newCpe3,
|
||||
String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(newCpe3, "UTF-8")));
|
||||
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe3, "UTF-8")));
|
||||
dependency.addIdentifier("cpe",
|
||||
newCpe4,
|
||||
String.format("http://web.nvd.nist.gov/view/vuln/search?cpe=%s", URLEncoder.encode(newCpe4, "UTF-8")));
|
||||
String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe4, "UTF-8")));
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
LOGGER.log(Level.FINE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes duplicate entries identified that are contained within JAR files. These occasionally crop up due to POM
|
||||
* entries or other types of files (such as DLLs and EXEs) being contained within the JAR.
|
||||
*
|
||||
* @param dependency the dependency that might be a duplicate
|
||||
* @param engine the engine used to scan all dependencies
|
||||
*/
|
||||
private void removeDuplicativeEntriesFromJar(Dependency dependency, Engine engine) {
|
||||
if (dependency.getFileName().toLowerCase().endsWith("pom.xml")
|
||||
|| "dll".equals(dependency.getFileExtension())
|
||||
|| "exe".equals(dependency.getFileExtension())) {
|
||||
String parentPath = dependency.getFilePath().toLowerCase();
|
||||
if (parentPath.contains(".jar")) {
|
||||
parentPath = parentPath.substring(0, parentPath.indexOf(".jar") + 4);
|
||||
final Dependency parent = findDependency(parentPath, engine.getDependencies());
|
||||
if (parent != null) {
|
||||
boolean remove = false;
|
||||
for (Identifier i : dependency.getIdentifiers()) {
|
||||
if ("cpe".equals(i.getType())) {
|
||||
final String trimmedCPE = trimCpeToVendor(i.getValue());
|
||||
for (Identifier parentId : parent.getIdentifiers()) {
|
||||
if ("cpe".equals(parentId.getType()) && parentId.getValue().startsWith(trimmedCPE)) {
|
||||
remove |= true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!remove) { //we can escape early
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (remove) {
|
||||
engine.getDependencies().remove(dependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a given dependency, based on a given path, from a list of dependencies.
|
||||
*
|
||||
* @param dependencyPath the path of the dependency to return
|
||||
* @param dependencies the collection of dependencies to search
|
||||
* @return the dependency object for the given path, otherwise null
|
||||
*/
|
||||
private Dependency findDependency(String dependencyPath, List<Dependency> dependencies) {
|
||||
for (Dependency d : dependencies) {
|
||||
if (d.getFilePath().equalsIgnoreCase(dependencyPath)) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a full CPE and returns the CPE trimmed to include only vendor and product.
|
||||
*
|
||||
* @param value the CPE value to trim
|
||||
* @return a CPE value that only includes the vendor and product
|
||||
*/
|
||||
private String trimCpeToVendor(String value) {
|
||||
//cpe:/a:jruby:jruby:1.0.8
|
||||
final int pos1 = value.indexOf(":", 7); //right of vendor
|
||||
final int pos2 = value.indexOf(":", pos1 + 1); //right of product
|
||||
if (pos2 < 0) {
|
||||
return value;
|
||||
} else {
|
||||
return value.substring(0, pos2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,6 @@ import org.owasp.dependencycheck.jaxb.pom.MavenNamespaceFilter;
|
||||
import org.owasp.dependencycheck.jaxb.pom.generated.License;
|
||||
import org.owasp.dependencycheck.jaxb.pom.generated.Model;
|
||||
import org.owasp.dependencycheck.jaxb.pom.generated.Organization;
|
||||
import org.owasp.dependencycheck.jaxb.pom.generated.Parent;
|
||||
import org.owasp.dependencycheck.utils.FileUtils;
|
||||
import org.owasp.dependencycheck.utils.NonClosingStream;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
@@ -74,7 +73,6 @@ import org.xml.sax.XMLFilter;
|
||||
import org.xml.sax.XMLReader;
|
||||
|
||||
/**
|
||||
*
|
||||
* Used to load a JAR file and collect information that can be used to determine the associated CPE.
|
||||
*
|
||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||
@@ -138,7 +136,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
"include-resource",
|
||||
"embed-dependency",
|
||||
"ipojo-components",
|
||||
"ipojo-extension");
|
||||
"ipojo-extension",
|
||||
"eclipse-sourcereferences");
|
||||
/**
|
||||
* item in some manifest, should be considered medium confidence.
|
||||
*/
|
||||
@@ -321,7 +320,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
|
||||
newDependency.setFileName(displayName);
|
||||
newDependency.setFilePath(displayPath);
|
||||
addPomEvidence(newDependency, pom, pomProperties);
|
||||
setPomEvidence(newDependency, pom, pomProperties, null);
|
||||
engine.getDependencies().add(newDependency);
|
||||
Collections.sort(engine.getDependencies());
|
||||
} else {
|
||||
@@ -558,10 +557,21 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
*/
|
||||
private boolean setPomEvidence(Dependency dependency, Model pom, Properties pomProperties, ArrayList<ClassNameInformation> classes) {
|
||||
boolean foundSomething = false;
|
||||
boolean addAsIdentifier = true;
|
||||
if (pom == null) {
|
||||
return foundSomething;
|
||||
}
|
||||
String groupid = interpolateString(pom.getGroupId(), pomProperties);
|
||||
String parentGroupId = null;
|
||||
|
||||
if (pom.getParent() != null) {
|
||||
parentGroupId = interpolateString(pom.getParent().getGroupId(), pomProperties);
|
||||
if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) {
|
||||
groupid = parentGroupId;
|
||||
}
|
||||
}
|
||||
final String originalGroupID = groupid;
|
||||
|
||||
if (groupid != null && !groupid.isEmpty()) {
|
||||
if (groupid.startsWith("org.") || groupid.startsWith("com.")) {
|
||||
groupid = groupid.substring(4);
|
||||
@@ -571,8 +581,26 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW);
|
||||
addMatchingValues(classes, groupid, dependency.getVendorEvidence());
|
||||
addMatchingValues(classes, groupid, dependency.getProductEvidence());
|
||||
if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) {
|
||||
dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM);
|
||||
dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW);
|
||||
addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence());
|
||||
addMatchingValues(classes, parentGroupId, dependency.getProductEvidence());
|
||||
}
|
||||
} else {
|
||||
addAsIdentifier = false;
|
||||
}
|
||||
|
||||
String artifactid = interpolateString(pom.getArtifactId(), pomProperties);
|
||||
String parentArtifactId = null;
|
||||
|
||||
if (pom.getParent() != null) {
|
||||
parentArtifactId = interpolateString(pom.getParent().getArtifactId(), pomProperties);
|
||||
if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) {
|
||||
artifactid = parentArtifactId;
|
||||
}
|
||||
}
|
||||
final String originalArtifactID = artifactid;
|
||||
if (artifactid != null && !artifactid.isEmpty()) {
|
||||
if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) {
|
||||
artifactid = artifactid.substring(4);
|
||||
@@ -582,13 +610,40 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW);
|
||||
addMatchingValues(classes, artifactid, dependency.getVendorEvidence());
|
||||
addMatchingValues(classes, artifactid, dependency.getProductEvidence());
|
||||
if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) {
|
||||
dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM);
|
||||
dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW);
|
||||
addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence());
|
||||
addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence());
|
||||
}
|
||||
} else {
|
||||
addAsIdentifier = false;
|
||||
}
|
||||
//version
|
||||
final String version = interpolateString(pom.getVersion(), pomProperties);
|
||||
String version = interpolateString(pom.getVersion(), pomProperties);
|
||||
String parentVersion = null;
|
||||
|
||||
if (pom.getParent() != null) {
|
||||
parentVersion = interpolateString(pom.getParent().getVersion(), pomProperties);
|
||||
if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) {
|
||||
version = parentVersion;
|
||||
}
|
||||
}
|
||||
|
||||
if (version != null && !version.isEmpty()) {
|
||||
foundSomething = true;
|
||||
dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST);
|
||||
if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) {
|
||||
dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW);
|
||||
}
|
||||
} else {
|
||||
addAsIdentifier = false;
|
||||
}
|
||||
|
||||
if (addAsIdentifier) {
|
||||
dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.LOW);
|
||||
}
|
||||
|
||||
// org name
|
||||
final Organization org = pom.getOrganization();
|
||||
if (org != null && org.getName() != null) {
|
||||
@@ -647,7 +702,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
//TODO remove weighting
|
||||
vendor.addWeighting(entry.getKey());
|
||||
if (addPackagesAsEvidence && entry.getKey().length() > 1) {
|
||||
vendor.addEvidence("jar", "package", entry.getKey(), Confidence.LOW);
|
||||
vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -656,7 +711,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
if (ratio > 0.5) {
|
||||
product.addWeighting(entry.getKey());
|
||||
if (addPackagesAsEvidence && entry.getKey().length() > 1) {
|
||||
product.addEvidence("jar", "package", entry.getKey(), Confidence.LOW);
|
||||
product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -690,7 +745,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
&& !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar")
|
||||
&& !dependency.getFileName().toLowerCase().endsWith("-src.jar")
|
||||
&& !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) {
|
||||
LOGGER.log(Level.INFO,
|
||||
LOGGER.log(Level.FINE,
|
||||
String.format("Jar file '%s' does not contain a manifest.",
|
||||
dependency.getFileName()));
|
||||
}
|
||||
@@ -764,6 +819,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
&& !key.endsWith("class-path")
|
||||
&& !key.endsWith("-scm") //todo change this to a regex?
|
||||
&& !key.startsWith("scm-")
|
||||
&& !value.trim().startsWith("scm:")
|
||||
&& !isImportPackage(key, value)
|
||||
&& !isPackage(key, value)) {
|
||||
|
||||
@@ -1111,7 +1167,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* @param evidence the evidence collection to add new entries too
|
||||
*/
|
||||
private void addMatchingValues(ArrayList<ClassNameInformation> classes, String value, EvidenceCollection evidence) {
|
||||
if (value == null || value.isEmpty()) {
|
||||
if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
final String text = value.toLowerCase();
|
||||
@@ -1138,93 +1194,6 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds evidence from the POM to the dependency. This includes the GAV and in some situations the parent GAV if
|
||||
* specified.
|
||||
*
|
||||
* @param dependency the dependency being analyzed
|
||||
* @param pom the POM data
|
||||
* @param pomProperties the properties file associated with the pom
|
||||
*/
|
||||
private void addPomEvidence(Dependency dependency, Model pom, Properties pomProperties) {
|
||||
if (pom == null) {
|
||||
return;
|
||||
}
|
||||
String groupid = interpolateString(pom.getGroupId(), pomProperties);
|
||||
if (groupid != null && !groupid.isEmpty()) {
|
||||
if (groupid.startsWith("org.") || groupid.startsWith("com.")) {
|
||||
groupid = groupid.substring(4);
|
||||
}
|
||||
dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGH);
|
||||
dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW);
|
||||
}
|
||||
String artifactid = interpolateString(pom.getArtifactId(), pomProperties);
|
||||
if (artifactid != null && !artifactid.isEmpty()) {
|
||||
if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) {
|
||||
artifactid = artifactid.substring(4);
|
||||
}
|
||||
dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGH);
|
||||
dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW);
|
||||
}
|
||||
final String version = interpolateString(pom.getVersion(), pomProperties);
|
||||
if (version != null && !version.isEmpty()) {
|
||||
dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST);
|
||||
}
|
||||
|
||||
final Parent parent = pom.getParent(); //grab parent GAV
|
||||
if (parent != null) {
|
||||
final String parentGroupId = interpolateString(parent.getGroupId(), pomProperties);
|
||||
if (parentGroupId != null && !parentGroupId.isEmpty()) {
|
||||
if (groupid == null || groupid.isEmpty()) {
|
||||
dependency.getVendorEvidence().addEvidence("pom", "parent.groupid", parentGroupId, Confidence.HIGH);
|
||||
} else {
|
||||
dependency.getVendorEvidence().addEvidence("pom", "parent.groupid", parentGroupId, Confidence.MEDIUM);
|
||||
}
|
||||
dependency.getProductEvidence().addEvidence("pom", "parent.groupid", parentGroupId, Confidence.LOW);
|
||||
}
|
||||
final String parentArtifactId = interpolateString(parent.getArtifactId(), pomProperties);
|
||||
if (parentArtifactId != null && !parentArtifactId.isEmpty()) {
|
||||
if (artifactid == null || artifactid.isEmpty()) {
|
||||
dependency.getProductEvidence().addEvidence("pom", "parent.artifactid", parentArtifactId, Confidence.HIGH);
|
||||
} else {
|
||||
dependency.getProductEvidence().addEvidence("pom", "parent.artifactid", parentArtifactId, Confidence.MEDIUM);
|
||||
}
|
||||
dependency.getVendorEvidence().addEvidence("pom", "parent.artifactid", parentArtifactId, Confidence.LOW);
|
||||
}
|
||||
final String parentVersion = interpolateString(parent.getVersion(), pomProperties);
|
||||
if (parentVersion != null && !parentVersion.isEmpty()) {
|
||||
if (version == null || version.isEmpty()) {
|
||||
dependency.getVersionEvidence().addEvidence("pom", "parent.version", parentVersion, Confidence.HIGH);
|
||||
} else {
|
||||
dependency.getVersionEvidence().addEvidence("pom", "parent.version", parentVersion, Confidence.LOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
// org name
|
||||
final Organization org = pom.getOrganization();
|
||||
if (org != null && org.getName() != null) {
|
||||
final String orgName = interpolateString(org.getName(), pomProperties);
|
||||
if (orgName != null && !orgName.isEmpty()) {
|
||||
dependency.getVendorEvidence().addEvidence("pom", "organization name", orgName, Confidence.HIGH);
|
||||
}
|
||||
}
|
||||
//pom name
|
||||
final String pomName = interpolateString(pom.getName(), pomProperties);
|
||||
if (pomName != null && !pomName.isEmpty()) {
|
||||
dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
|
||||
dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
|
||||
}
|
||||
|
||||
//Description
|
||||
if (pom.getDescription() != null) {
|
||||
final String description = interpolateString(pom.getDescription(), pomProperties);
|
||||
if (description != null && !description.isEmpty()) {
|
||||
addDescription(dependency, description, "pom", "description");
|
||||
}
|
||||
}
|
||||
extractLicense(pom, pomProperties, dependency);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the license information from the pom and adds it to the dependency.
|
||||
*
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.owasp.dependencycheck.data.nexus.MavenArtifact;
|
||||
import org.owasp.dependencycheck.data.nexus.NexusSearch;
|
||||
import org.owasp.dependencycheck.dependency.Confidence;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
import org.owasp.dependencycheck.dependency.Identifier;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
|
||||
/**
|
||||
@@ -161,7 +162,18 @@ public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
dependency.getVersionEvidence().addEvidence("nexus", "version", ma.getVersion(), Confidence.HIGH);
|
||||
}
|
||||
if (ma.getArtifactUrl() != null && !"".equals(ma.getArtifactUrl())) {
|
||||
dependency.addIdentifier("maven", ma.toString(), ma.getArtifactUrl(), Confidence.HIGHEST);
|
||||
boolean found = false;
|
||||
for (Identifier i : dependency.getIdentifiers()) {
|
||||
if ("maven".equals(i.getType()) && i.getValue().equals(ma.toString())) {
|
||||
found = true;
|
||||
i.setConfidence(Confidence.HIGHEST);
|
||||
i.setUrl(ma.getArtifactUrl());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
dependency.addIdentifier("maven", ma.toString(), ma.getArtifactUrl(), Confidence.HIGHEST);
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException iae) {
|
||||
//dependency.addAnalysisException(new AnalysisException("Invalid SHA-1"));
|
||||
|
||||
@@ -64,7 +64,7 @@ public class NexusSearch {
|
||||
public NexusSearch(URL rootURL) {
|
||||
this.rootURL = rootURL;
|
||||
try {
|
||||
if (null != Settings.getString(Settings.KEYS.PROXY_URL)
|
||||
if (null != Settings.getString(Settings.KEYS.PROXY_SERVER)
|
||||
&& Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY)) {
|
||||
useProxy = true;
|
||||
LOGGER.fine("Using proxy");
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.owasp.dependencycheck.utils.Pair;
|
||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||
*/
|
||||
public class CveDB {
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*/
|
||||
@@ -247,6 +248,7 @@ public class CveDB {
|
||||
/**
|
||||
* SQL Statement to retrieve a property from the database.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private static final String SELECT_PROPERTY = "SELECT id, value FROM properties WHERE id = ?";
|
||||
/**
|
||||
* SQL Statement to insert a new property.
|
||||
@@ -259,6 +261,7 @@ public class CveDB {
|
||||
/**
|
||||
* SQL Statement to delete a property.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private static final String DELETE_PROPERTY = "DELETE FROM properties WHERE id = ?";
|
||||
|
||||
//</editor-fold>
|
||||
@@ -733,8 +736,10 @@ public class CveDB {
|
||||
final boolean isStruts = "apache".equals(vendor) && "struts".equals(product);
|
||||
final DependencyVersion v = parseDependencyVersion(cpeId);
|
||||
final boolean prevAffected = previous != null && !previous.isEmpty();
|
||||
if (identifiedVersion == null || "-".equals(identifiedVersion.toString())) {
|
||||
if (v == null || "-".equals(v.toString())) {
|
||||
if (v == null || "-".equals(v.toString())) { //all versions
|
||||
affected = true;
|
||||
} else if (identifiedVersion == null || "-".equals(identifiedVersion.toString())) {
|
||||
if (prevAffected) {
|
||||
affected = true;
|
||||
}
|
||||
} else if (identifiedVersion.equals(v) || (prevAffected && identifiedVersion.compareTo(v) < 0)) {
|
||||
|
||||
@@ -34,7 +34,7 @@ import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
|
||||
import static org.owasp.dependencycheck.data.nvdcve.DatabaseProperties.MODIFIED;
|
||||
import org.owasp.dependencycheck.data.update.exception.InvalidDataException;
|
||||
import org.owasp.dependencycheck.data.update.exception.UpdateException;
|
||||
import org.owasp.dependencycheck.data.update.task.CallableDownloadTask;
|
||||
import org.owasp.dependencycheck.data.update.task.DownloadTask;
|
||||
import org.owasp.dependencycheck.data.update.task.ProcessTask;
|
||||
import org.owasp.dependencycheck.utils.DownloadFailedException;
|
||||
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||
@@ -122,7 +122,7 @@ public class StandardUpdate {
|
||||
final Set<Future<Future<ProcessTask>>> downloadFutures = new HashSet<Future<Future<ProcessTask>>>(maxUpdates);
|
||||
for (NvdCveInfo cve : updateable) {
|
||||
if (cve.getNeedsUpdate()) {
|
||||
final CallableDownloadTask call = new CallableDownloadTask(cve, processExecutor, cveDB, Settings.getInstance());
|
||||
final DownloadTask call = new DownloadTask(cve, processExecutor, cveDB, Settings.getInstance());
|
||||
downloadFutures.add(downloadExecutors.submit(call));
|
||||
}
|
||||
}
|
||||
@@ -178,7 +178,9 @@ public class StandardUpdate {
|
||||
|
||||
if (maxUpdates >= 1) { //ensure the modified file date gets written (we may not have actually updated it)
|
||||
properties.save(updateable.get(MODIFIED));
|
||||
LOGGER.log(Level.INFO, "Begin database maintenance.");
|
||||
cveDB.cleanupDatabase();
|
||||
LOGGER.log(Level.INFO, "End database maintenance.");
|
||||
}
|
||||
} finally {
|
||||
closeDataStores();
|
||||
|
||||
@@ -37,12 +37,12 @@ import org.owasp.dependencycheck.utils.Settings;
|
||||
*
|
||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||
*/
|
||||
public class CallableDownloadTask implements Callable<Future<ProcessTask>> {
|
||||
public class DownloadTask implements Callable<Future<ProcessTask>> {
|
||||
|
||||
/**
|
||||
* The Logger.
|
||||
*/
|
||||
private static final Logger LOGGER = Logger.getLogger(CallableDownloadTask.class.getName());
|
||||
private static final Logger LOGGER = Logger.getLogger(DownloadTask.class.getName());
|
||||
|
||||
/**
|
||||
* Simple constructor for the callable download task.
|
||||
@@ -54,7 +54,7 @@ public class CallableDownloadTask implements Callable<Future<ProcessTask>> {
|
||||
* the dependencies have a correct reference to the global settings.
|
||||
* @throws UpdateException thrown if temporary files could not be created
|
||||
*/
|
||||
public CallableDownloadTask(NvdCveInfo nvdCveInfo, ExecutorService processor, CveDB cveDB, Settings settings) throws UpdateException {
|
||||
public DownloadTask(NvdCveInfo nvdCveInfo, ExecutorService processor, CveDB cveDB, Settings settings) throws UpdateException {
|
||||
this.nvdCveInfo = nvdCveInfo;
|
||||
this.processorService = processor;
|
||||
this.cveDB = cveDB;
|
||||
@@ -203,7 +203,7 @@ public class CallableDownloadTask implements Callable<Future<ProcessTask>> {
|
||||
LOGGER.log(Level.WARNING, msg);
|
||||
LOGGER.log(Level.FINE, "Download Task Failed", ex);
|
||||
} finally {
|
||||
Settings.cleanup();
|
||||
Settings.cleanup(false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -79,7 +79,7 @@ public class ProcessTask implements Callable<ProcessTask> {
|
||||
/**
|
||||
* A reference to the callable download task.
|
||||
*/
|
||||
private final CallableDownloadTask filePair;
|
||||
private final DownloadTask filePair;
|
||||
/**
|
||||
* A reference to the properties.
|
||||
*/
|
||||
@@ -97,7 +97,7 @@ public class ProcessTask implements Callable<ProcessTask> {
|
||||
* @param settings a reference to the global settings object; this is necessary so that when the thread is started
|
||||
* the dependencies have a correct reference to the global settings.
|
||||
*/
|
||||
public ProcessTask(final CveDB cveDB, final CallableDownloadTask filePair, Settings settings) {
|
||||
public ProcessTask(final CveDB cveDB, final DownloadTask filePair, Settings settings) {
|
||||
this.cveDB = cveDB;
|
||||
this.filePair = filePair;
|
||||
this.properties = cveDB.getDatabaseProperties();
|
||||
@@ -119,7 +119,7 @@ public class ProcessTask implements Callable<ProcessTask> {
|
||||
} catch (UpdateException ex) {
|
||||
this.exception = ex;
|
||||
} finally {
|
||||
Settings.cleanup();
|
||||
Settings.cleanup(false);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -177,6 +177,33 @@ public class Dependency implements Comparable<Dependency> {
|
||||
this.filePath = filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* The file name to display in reports.
|
||||
*/
|
||||
private String displayName = null;
|
||||
|
||||
/**
|
||||
* Sets the file name to display in reports.
|
||||
*
|
||||
* @param displayName the name to display
|
||||
*/
|
||||
public void setDisplayFileName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file name to display in reports; if no display file name has been set it will default to the actual
|
||||
* file name.
|
||||
*
|
||||
* @return the file name to display
|
||||
*/
|
||||
public String getDisplayFileName() {
|
||||
if (displayName == null) {
|
||||
return this.fileName;
|
||||
}
|
||||
return this.displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Gets the file path of the dependency.</p>
|
||||
@@ -369,6 +396,15 @@ public class Dependency implements Comparable<Dependency> {
|
||||
return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the evidence used to identify this dependency.
|
||||
*
|
||||
* @return an EvidenceCollection.
|
||||
*/
|
||||
public Set<Evidence> getEvidenceForDisplay() {
|
||||
return EvidenceCollection.mergeForDisplay(this.productEvidence, this.vendorEvidence, this.versionEvidence);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the evidence used to identify this dependency.
|
||||
*
|
||||
|
||||
@@ -220,22 +220,95 @@ public class Evidence implements Comparable<Evidence> {
|
||||
* @return an integer indicating the ordering of the two objects
|
||||
*/
|
||||
public int compareTo(Evidence o) {
|
||||
if (source.equals(o.source)) {
|
||||
if (name.equals(o.name)) {
|
||||
if (value.equals(o.value)) {
|
||||
if (confidence.equals(o.confidence)) {
|
||||
if (o == null) {
|
||||
return 1;
|
||||
}
|
||||
if (equalsWithNullCheck(source, o.source)) {
|
||||
if (equalsWithNullCheck(name, o.name)) {
|
||||
if (equalsWithNullCheck(value, o.value)) {
|
||||
if (equalsWithNullCheck(confidence, o.confidence)) {
|
||||
return 0; //they are equal
|
||||
} else {
|
||||
return confidence.compareTo(o.confidence);
|
||||
return compareToWithNullCheck(confidence, o.confidence);
|
||||
}
|
||||
} else {
|
||||
return value.compareToIgnoreCase(o.value);
|
||||
return compareToIgnoreCaseWithNullCheck(value, o.value);
|
||||
}
|
||||
} else {
|
||||
return name.compareToIgnoreCase(o.name);
|
||||
return compareToIgnoreCaseWithNullCheck(name, o.name);
|
||||
}
|
||||
} else {
|
||||
return source.compareToIgnoreCase(o.source);
|
||||
return compareToIgnoreCaseWithNullCheck(source, o.source);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Equality check with an exhaustive, possibly duplicative, check against nulls.
|
||||
*
|
||||
* @param me the value to be compared
|
||||
* @param other the other value to be compared
|
||||
* @return true if the values are equal; otherwise false
|
||||
*/
|
||||
private boolean equalsWithNullCheck(String me, String other) {
|
||||
if (me == null && other == null) {
|
||||
return true;
|
||||
} else if (me == null || other == null) {
|
||||
return false;
|
||||
}
|
||||
return me.equals(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equality check with an exhaustive, possibly duplicative, check against nulls.
|
||||
*
|
||||
* @param me the value to be compared
|
||||
* @param other the other value to be compared
|
||||
* @return true if the values are equal; otherwise false
|
||||
*/
|
||||
private boolean equalsWithNullCheck(Confidence me, Confidence other) {
|
||||
if (me == null && other == null) {
|
||||
return true;
|
||||
} else if (me == null || other == null) {
|
||||
return false;
|
||||
}
|
||||
return me.equals(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around {@link java.lang.String#compareToIgnoreCase(java.lang.String) String.compareToIgnoreCase} with an
|
||||
* exhaustive, possibly duplicative, check against nulls.
|
||||
*
|
||||
* @param me the value to be compared
|
||||
* @param other the other value to be compared
|
||||
* @return true if the values are equal; otherwise false
|
||||
*/
|
||||
private int compareToIgnoreCaseWithNullCheck(String me, String other) {
|
||||
if (me == null && other == null) {
|
||||
return 0;
|
||||
} else if (me == null) {
|
||||
return -1; //the other string is greater then me
|
||||
} else if (other == null) {
|
||||
return 1; //me is greater then the other string
|
||||
}
|
||||
return me.compareToIgnoreCase(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around {@link java.lang.Enum#compareTo(java.lang.Enum) Enum.compareTo} with an exhaustive, possibly
|
||||
* duplicative, check against nulls.
|
||||
*
|
||||
* @param me the value to be compared
|
||||
* @param other the other value to be compared
|
||||
* @return true if the values are equal; otherwise false
|
||||
*/
|
||||
private int compareToWithNullCheck(Confidence me, Confidence other) {
|
||||
if (me == null && other == null) {
|
||||
return 0;
|
||||
} else if (me == null) {
|
||||
return -1; //the other string is greater then me
|
||||
} else if (other == null) {
|
||||
return 1; //me is greater then the other string
|
||||
}
|
||||
return me.compareTo(other);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,6 +311,26 @@ public class EvidenceCollection implements Iterable<Evidence> {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges multiple EvidenceCollections together; flattening all of the evidence items by removing the confidence.
|
||||
*
|
||||
* @param ec One or more EvidenceCollections
|
||||
* @return new set of evidence resulting from merging the evidence in the collections
|
||||
*/
|
||||
public static Set<Evidence> mergeForDisplay(EvidenceCollection... ec) {
|
||||
final Set<Evidence> ret = new TreeSet<Evidence>();
|
||||
for (EvidenceCollection col : ec) {
|
||||
for (Evidence e : col) {
|
||||
if (e.isUsed()) {
|
||||
final Evidence newEvidence = new Evidence(e.getSource(), e.getName(), e.getValue(), null);
|
||||
newEvidence.setUsed(true);
|
||||
ret.add(newEvidence);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string of evidence 'values'.
|
||||
*
|
||||
|
||||
@@ -77,19 +77,19 @@ public class VulnerableSoftware extends IndexEntry implements Serializable, Comp
|
||||
if (cpeName != null && cpeName.length() > 7) {
|
||||
final String[] data = cpeName.substring(7).split(":");
|
||||
if (data.length >= 1) {
|
||||
this.setVendor(URLDecoder.decode(data[0].replace("+", "%2B"), "UTF-8"));
|
||||
this.setVendor(urlDecode(data[0]));
|
||||
}
|
||||
if (data.length >= 2) {
|
||||
this.setProduct(URLDecoder.decode(data[1].replace("+", "%2B"), "UTF-8"));
|
||||
this.setProduct(urlDecode(data[1]));
|
||||
}
|
||||
if (data.length >= 3) {
|
||||
version = URLDecoder.decode(data[2].replace("+", "%2B"), "UTF-8");
|
||||
version = urlDecode(data[2]);
|
||||
}
|
||||
if (data.length >= 4) {
|
||||
revision = URLDecoder.decode(data[3].replace("+", "%2B"), "UTF-8");
|
||||
revision = urlDecode(data[3]);
|
||||
}
|
||||
if (data.length >= 5) {
|
||||
edition = URLDecoder.decode(data[4].replace("+", "%2B"), "UTF-8");
|
||||
edition = urlDecode(data[4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -341,4 +341,25 @@ public class VulnerableSoftware extends IndexEntry implements Serializable, Comp
|
||||
public void setEdition(String edition) {
|
||||
this.edition = edition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces '+' with '%2B' and then URL Decodes the string attempting first UTF-8, then ASCII, then default.
|
||||
*
|
||||
* @param string the string to URL Decode
|
||||
* @return the URL Decoded string
|
||||
*/
|
||||
private String urlDecode(String string) {
|
||||
final String text = string.replace("+", "%2B");
|
||||
String result;
|
||||
try {
|
||||
result = URLDecoder.decode(text, "UTF-8");
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
try {
|
||||
result = URLDecoder.decode(text, "ASCII");
|
||||
} catch (UnsupportedEncodingException ex1) {
|
||||
result = URLDecoder.decode(text);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,10 @@ public class SuppressionHandler extends DefaultHandler {
|
||||
* The CWE element name.
|
||||
*/
|
||||
public static final String CWE = "cwe";
|
||||
/**
|
||||
* The GAV element name.
|
||||
*/
|
||||
public static final String GAV = "gav";
|
||||
/**
|
||||
* The cvssBelow element name.
|
||||
*/
|
||||
@@ -95,13 +99,10 @@ public class SuppressionHandler extends DefaultHandler {
|
||||
*/
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||
currentAttributes = null;
|
||||
currentAttributes = attributes;
|
||||
currentText = new StringBuffer();
|
||||
|
||||
if (SUPPRESS.equals(qName)) {
|
||||
rule = new SuppressionRule();
|
||||
} else if (FILE_PATH.equals(qName)) {
|
||||
currentAttributes = attributes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +124,9 @@ public class SuppressionHandler extends DefaultHandler {
|
||||
rule.setFilePath(pt);
|
||||
} else if (SHA1.equals(qName)) {
|
||||
rule.setSha1(currentText.toString());
|
||||
} else if (GAV.equals(qName)) {
|
||||
final PropertyType pt = processPropertyType();
|
||||
rule.setGav(pt);
|
||||
} else if (CPE.equals(qName)) {
|
||||
final PropertyType pt = processPropertyType();
|
||||
rule.addCpe(pt);
|
||||
|
||||
@@ -234,6 +234,37 @@ public class SuppressionRule {
|
||||
public boolean hasCve() {
|
||||
return cve.size() > 0;
|
||||
}
|
||||
/**
|
||||
* A Maven GAV to suppression.
|
||||
*/
|
||||
private PropertyType gav = null;
|
||||
|
||||
/**
|
||||
* Get the value of Maven GAV.
|
||||
*
|
||||
* @return the value of gav
|
||||
*/
|
||||
public PropertyType getGav() {
|
||||
return gav;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of Maven GAV.
|
||||
*
|
||||
* @param gav new value of Maven gav
|
||||
*/
|
||||
public void setGav(PropertyType gav) {
|
||||
this.gav = gav;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not this suppression rule as GAV entries.
|
||||
*
|
||||
* @return whether or not this suppression rule as GAV entries
|
||||
*/
|
||||
public boolean hasGav() {
|
||||
return gav != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a given dependency to determine if any CPE, CVE, CWE, or CVSS scores should be suppressed. If any
|
||||
@@ -248,12 +279,27 @@ public class SuppressionRule {
|
||||
if (sha1 != null && !sha1.equalsIgnoreCase(dependency.getSha1sum())) {
|
||||
return;
|
||||
}
|
||||
if (gav != null) {
|
||||
final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
|
||||
boolean gavFound = false;
|
||||
while (itr.hasNext()) {
|
||||
final Identifier i = itr.next();
|
||||
if (identifierMatches("maven", this.gav, i)) {
|
||||
gavFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!gavFound) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.hasCpe()) {
|
||||
final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
|
||||
while (itr.hasNext()) {
|
||||
final Identifier i = itr.next();
|
||||
for (PropertyType c : this.cpe) {
|
||||
if (cpeMatches(c, i)) {
|
||||
if (identifierMatches("cpe", c, i)) {
|
||||
dependency.addSuppressedIdentifier(i);
|
||||
itr.remove();
|
||||
break;
|
||||
@@ -309,7 +355,7 @@ public class SuppressionRule {
|
||||
boolean cpeHasNoVersion(PropertyType c) {
|
||||
if (c.isRegex()) {
|
||||
return false;
|
||||
} // cpe:/a:jboss:jboss:1.0.0:
|
||||
}
|
||||
if (countCharacter(c.getValue(), ':') == 3) {
|
||||
return true;
|
||||
}
|
||||
@@ -336,26 +382,75 @@ public class SuppressionRule {
|
||||
/**
|
||||
* Determines if the cpeEntry specified as a PropertyType matches the given Identifier.
|
||||
*
|
||||
* @param cpeEntry a suppression rule entry
|
||||
* @param identifierType the type of identifier ("cpe", "maven", etc.)
|
||||
* @param suppressionEntry a suppression rule entry
|
||||
* @param identifier a CPE identifier to check
|
||||
* @return true if the entry matches; otherwise false
|
||||
*/
|
||||
boolean cpeMatches(PropertyType cpeEntry, Identifier identifier) {
|
||||
if (cpeEntry.matches(identifier.getValue())) {
|
||||
return true;
|
||||
} else if (cpeHasNoVersion(cpeEntry)) {
|
||||
if (cpeEntry.isCaseSensitive()) {
|
||||
if (identifier.getValue().startsWith(cpeEntry.getValue())) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
final String id = identifier.getValue().toLowerCase();
|
||||
final String check = cpeEntry.getValue().toLowerCase();
|
||||
if (id.startsWith(check)) {
|
||||
return true;
|
||||
boolean identifierMatches(String identifierType, PropertyType suppressionEntry, Identifier identifier) {
|
||||
if (identifierType.equals(identifier.getType())) {
|
||||
if (suppressionEntry.matches(identifier.getValue())) {
|
||||
return true;
|
||||
} else if ("cpe".equals(identifierType) && cpeHasNoVersion(suppressionEntry)) {
|
||||
if (suppressionEntry.isCaseSensitive()) {
|
||||
return identifier.getValue().startsWith(suppressionEntry.getValue());
|
||||
} else {
|
||||
final String id = identifier.getValue().toLowerCase();
|
||||
final String check = suppressionEntry.getValue().toLowerCase();
|
||||
return id.startsWith(check);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard toString implementation.
|
||||
*
|
||||
* @return a string representation of this object
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("SuppressionRule{");
|
||||
if (filePath != null) {
|
||||
sb.append("filePath=").append(filePath).append(",");
|
||||
}
|
||||
if (sha1 != null) {
|
||||
sb.append("sha1=").append(sha1).append(",");
|
||||
}
|
||||
if (gav != null) {
|
||||
sb.append("gav=").append(gav).append(",");
|
||||
}
|
||||
if (cpe != null && cpe.size() > 0) {
|
||||
sb.append("cpe={");
|
||||
for (PropertyType pt : cpe) {
|
||||
sb.append(pt).append(",");
|
||||
}
|
||||
sb.append("}");
|
||||
}
|
||||
if (cwe != null && cwe.size() > 0) {
|
||||
sb.append("cwe={");
|
||||
for (String s : cwe) {
|
||||
sb.append(s).append(",");
|
||||
}
|
||||
sb.append("}");
|
||||
}
|
||||
if (cve != null && cve.size() > 0) {
|
||||
sb.append("cve={");
|
||||
for (String s : cve) {
|
||||
sb.append(s).append(",");
|
||||
}
|
||||
sb.append("}");
|
||||
}
|
||||
if (cvssBelow != null && cvssBelow.size() > 0) {
|
||||
sb.append("cvssBelow={");
|
||||
for (Float s : cvssBelow) {
|
||||
sb.append(s).append(",");
|
||||
}
|
||||
sb.append("}");
|
||||
}
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* This file is part of dependency-check-core.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.utils;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import static org.owasp.dependencycheck.utils.FileUtils.getFileExtension;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||
*/
|
||||
public final class ExtractionUtil {
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*/
|
||||
private static final Logger LOGGER = Logger.getLogger(ExtractionUtil.class.getName());
|
||||
/**
|
||||
* The buffer size to use when extracting files from the archive.
|
||||
*/
|
||||
private static final int BUFFER_SIZE = 4096;
|
||||
|
||||
/**
|
||||
* Private constructor for a utility class.
|
||||
*/
|
||||
private ExtractionUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the contents of an archive into the specified directory.
|
||||
*
|
||||
* @param archive an archive file such as a WAR or EAR
|
||||
* @param extractTo a directory to extract the contents to
|
||||
* @throws ExtractionException thrown if an exception occurs while extracting the files
|
||||
*/
|
||||
public static void extractFiles(File archive, File extractTo) throws ExtractionException {
|
||||
extractFiles(archive, extractTo, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the contents of an archive into the specified directory. The files are only extracted if they are
|
||||
* supported by the analyzers loaded into the specified engine. If the engine is specified as null then all files
|
||||
* are extracted.
|
||||
*
|
||||
* @param archive an archive file such as a WAR or EAR
|
||||
* @param extractTo a directory to extract the contents to
|
||||
* @param engine the scanning engine
|
||||
* @throws ExtractionException thrown if there is an error extracting the files
|
||||
*/
|
||||
public static void extractFiles(File archive, File extractTo, Engine engine) throws ExtractionException {
|
||||
if (archive == null || extractTo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
FileInputStream fis = null;
|
||||
ZipInputStream zis = null;
|
||||
|
||||
try {
|
||||
fis = new FileInputStream(archive);
|
||||
} catch (FileNotFoundException ex) {
|
||||
LOGGER.log(Level.FINE, null, ex);
|
||||
throw new ExtractionException("Archive file was not found.", ex);
|
||||
}
|
||||
zis = new ZipInputStream(new BufferedInputStream(fis));
|
||||
ZipEntry entry;
|
||||
try {
|
||||
while ((entry = zis.getNextEntry()) != null) {
|
||||
if (entry.isDirectory()) {
|
||||
final File d = new File(extractTo, entry.getName());
|
||||
if (!d.exists() && !d.mkdirs()) {
|
||||
final String msg = String.format("Unable to create '%s'.", d.getAbsolutePath());
|
||||
throw new ExtractionException(msg);
|
||||
}
|
||||
} else {
|
||||
final File file = new File(extractTo, entry.getName());
|
||||
final String ext = getFileExtension(file.getName());
|
||||
if (engine == null || engine.supportsExtension(ext)) {
|
||||
BufferedOutputStream bos = null;
|
||||
FileOutputStream fos;
|
||||
try {
|
||||
fos = new FileOutputStream(file);
|
||||
bos = new BufferedOutputStream(fos, BUFFER_SIZE);
|
||||
int count;
|
||||
final byte data[] = new byte[BUFFER_SIZE];
|
||||
while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) {
|
||||
bos.write(data, 0, count);
|
||||
}
|
||||
bos.flush();
|
||||
} catch (FileNotFoundException ex) {
|
||||
LOGGER.log(Level.FINE, null, ex);
|
||||
final String msg = String.format("Unable to find file '%s'.", file.getName());
|
||||
throw new ExtractionException(msg, ex);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.FINE, null, ex);
|
||||
final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
|
||||
throw new ExtractionException(msg, ex);
|
||||
} finally {
|
||||
if (bos != null) {
|
||||
try {
|
||||
bos.close();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.FINEST, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
final String msg = String.format("Exception reading archive '%s'.", archive.getName());
|
||||
LOGGER.log(Level.FINE, msg, ex);
|
||||
throw new ExtractionException(msg, ex);
|
||||
} finally {
|
||||
try {
|
||||
zis.close();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.FINEST, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<suppressions xmlns="https://www.owasp.org/index.php/OWASP_Dependency_Check_Suppression">
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
This suppresses false positives identified on spring security.
|
||||
]]></notes>
|
||||
<gav regex="true">org\.springframework\.security:spring.*</gav>
|
||||
<cpe>cpe:/a:mod_security:mod_security</cpe>
|
||||
<cpe>cpe:/a:springsource:spring_framework</cpe>
|
||||
<cpe>cpe:/a:vmware:springsource_spring_framework</cpe>
|
||||
</suppress>
|
||||
</suppressions>
|
||||
@@ -0,0 +1,10 @@
|
||||
analyzer.AssemblyAnalyzer.notdeployed=GrokAssembly didn't get deployed
|
||||
analyzer.AssemblyAnalyzer.grokassembly.stderr=Error from GrokAssembly: {0}
|
||||
analyzer.AssemblyAnalyzer.notassembly={0} is not a .NET assembly or executable and as such cannot be analyzed by dependency-check
|
||||
analyzer.AssemblyAnalyzer.grokassembly.rc=Return code {0} from GrokAssembly
|
||||
analyzer.AssemblyAnalyzer.grokassembly.deployed=Extracted GrokAssembly.exe to {0}
|
||||
analyzer.AssemblyAnalyzer.grokassembly.notdeployed=Could not extract GrokAssembly.exe: {0}
|
||||
analyzer.AssemblyAnalyzer.grokassembly.initialization.failed=An error occurred with the .NET AssemblyAnalyzer; \
|
||||
this can be ignored unless you are scanning .NET DLLs. Please see the log for more details.
|
||||
analyzer.AssemblyAnalyzer.grokassembly.initialization.message=Could not execute GrokAssembly {0}
|
||||
analyzer.AssemblyAnalyzer.grokassembly.notdeleted=Can't delete temporary GrokAssembly.exe
|
||||
@@ -41,6 +41,7 @@
|
||||
<xs:choice minOccurs="0" maxOccurs="1">
|
||||
<xs:element name="filePath" type="dc:regexStringType"/>
|
||||
<xs:element name="sha1" type="dc:sha1Type"/>
|
||||
<xs:element name="gav" type="dc:regexStringType"/>
|
||||
</xs:choice>
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="cpe" type="dc:regexStringType"/>
|
||||
|
||||
@@ -532,11 +532,11 @@ arising out of or in connection with the use of this tool, the analysis performe
|
||||
#foreach($dependency in $dependencies)
|
||||
#set($lnkcnt=$lnkcnt+1)
|
||||
<li class="#if($dependency.getVulnerabilities().size()==0)notvulnerable#else vulnerable#end">
|
||||
<a href="#l${lnkcnt}_$enc.html($enc.url($dependency.Sha1sum))">$enc.html($dependency.FileName)</a>
|
||||
<a href="#l${lnkcnt}_$enc.html($enc.url($dependency.Sha1sum))">$enc.html($dependency.DisplayFileName)</a>
|
||||
#if($dependency.getRelatedDependencies().size()>0)
|
||||
<ul>
|
||||
#foreach($related in $dependency.getRelatedDependencies())
|
||||
<li>$enc.html($related.FileName)</li>
|
||||
<li>$enc.html($related.DisplayFileName)</li>
|
||||
#end
|
||||
</ul>
|
||||
#end
|
||||
@@ -549,7 +549,7 @@ arising out of or in connection with the use of this tool, the analysis performe
|
||||
#set($vsctr=0) ##counter to create unique groups for vulnerable software
|
||||
#foreach($dependency in $dependencies)
|
||||
#set($lnkcnt=$lnkcnt+1)
|
||||
<h3 class="subsectionheader standardsubsection#if($dependency.getVulnerabilities().size()==0) notvulnerable#end"><a name="l${lnkcnt}_$enc.html($dependency.Sha1sum)"></a>$enc.html($dependency.FileName)</h3>
|
||||
<h3 class="subsectionheader standardsubsection#if($dependency.getVulnerabilities().size()==0) notvulnerable#end"><a name="l${lnkcnt}_$enc.html($dependency.Sha1sum)"></a>$enc.html($dependency.DisplayFileName)</h3>
|
||||
<div class="subsectioncontent#if($dependency.getVulnerabilities().size()==0) notvulnerable#end">
|
||||
#if ($dependency.description)
|
||||
<p><b>Description:</b> $enc.html($dependency.description)<br/></p>
|
||||
@@ -571,7 +571,7 @@ arising out of or in connection with the use of this tool, the analysis performe
|
||||
<div id="content$cnt" class="subsectioncontent standardsubsection hidden">
|
||||
<table class="lined fullwidth" border="0">
|
||||
<tr><th class="left" style="width:10%;">Source</th><th class="left" style="width:20%;">Name</th><th class="left" style="width:70%;">Value</th></tr>
|
||||
#foreach($evidence in $dependency.getEvidenceUsed())
|
||||
#foreach($evidence in $dependency.getEvidenceForDisplay())
|
||||
<tr><td>$enc.html($evidence.getSource())</td><td>$enc.html($evidence.getName())</td><td>$enc.html($evidence.getValue())</td></tr>
|
||||
#end
|
||||
</table>
|
||||
@@ -582,7 +582,7 @@ arising out of or in connection with the use of this tool, the analysis performe
|
||||
<div id="content$cnt" class="subsectioncontent standardsubsection hidden">
|
||||
<ul>
|
||||
#foreach($related in $dependency.getRelatedDependencies())
|
||||
<li>$enc.html($related.FileName)
|
||||
<li>$enc.html($related.DisplayFileName)
|
||||
<ul>
|
||||
<li>File Path: $enc.html($related.FilePath)</li>
|
||||
<li>SHA1: $enc.html($related.Sha1sum)</li>
|
||||
@@ -612,7 +612,7 @@ arising out of or in connection with the use of this tool, the analysis performe
|
||||
#end
|
||||
#end
|
||||
<h4 id="header$cnt" class="subsectionheader white">Identifiers</h4>
|
||||
##: <a href="http://web.nvd.nist.gov/view/vuln/search-results?cpe=$enc.url($cpevalue)" target="_blank">$enc.html($cpevalue)</a></h4>
|
||||
##: <a href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($cpevalue)" target="_blank">$enc.html($cpevalue)</a></h4>
|
||||
<div id="content$cnt" class="subsectioncontent standardsubsection">
|
||||
#if ($dependency.getIdentifiers().size()==0)
|
||||
<ul><li><b>None</b></li></ul>
|
||||
@@ -668,13 +668,20 @@ arising out of or in connection with the use of this tool, the analysis performe
|
||||
</ul>
|
||||
#end
|
||||
</p>
|
||||
<p>Vulnerable Software & Versions: (<a href="#" onclick="toggleDisplay(this,'.vs$vsctr'); return false;">show all</a>)<ul>
|
||||
<li class="vs$vsctr"><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/search-results?cpe=$enc.url($vuln.matchedCPE)">$enc.html($vuln.matchedCPE)</a> #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end</li>
|
||||
<li class="vs$vsctr">...</li>
|
||||
#foreach($vs in $vuln.getVulnerableSoftware())
|
||||
<li class="vs$vsctr hidden"><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/search-results?cpe=$enc.url($vs.name)">$enc.html($vs.name)</a> #if($vs.hasPreviousVersion()) and all previous versions#end</li>
|
||||
|
||||
#if ($vuln.getVulnerableSoftware().size()<2)
|
||||
<p>Vulnerable Software & Versions:<ul>
|
||||
<li class="vs$vsctr"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vuln.matchedCPE)">$enc.html($vuln.matchedCPE)</a> #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end</li>
|
||||
</ul></p>
|
||||
#else
|
||||
<p>Vulnerable Software & Versions: (<a href="#" onclick="toggleDisplay(this,'.vs$vsctr'); return false;">show all</a>)<ul>
|
||||
<li class="vs$vsctr"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vuln.matchedCPE)">$enc.html($vuln.matchedCPE)</a> #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end</li>
|
||||
<li class="vs$vsctr">...</li>
|
||||
#foreach($vs in $vuln.getVulnerableSoftware())
|
||||
<li class="vs$vsctr hidden"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vs.name)">$enc.html($vs.name)</a> #if($vs.hasPreviousVersion()) and all previous versions#end</li>
|
||||
#end
|
||||
</ul></p>
|
||||
#end
|
||||
</ul></p>
|
||||
#end
|
||||
</div>
|
||||
#end
|
||||
@@ -692,7 +699,7 @@ arising out of or in connection with the use of this tool, the analysis performe
|
||||
#foreach($dependency in $dependencies)
|
||||
#if ($dependency.getSuppressedIdentifiers().size()>0 || $dependency.getSuppressedVulnerabilities().size()>0)
|
||||
#set($lnkcnt=$lnkcnt+1)
|
||||
<h3 class="subsectionheader standardsubsection">$enc.html($dependency.FileName)</h3>
|
||||
<h3 class="subsectionheader standardsubsection">$enc.html($dependency.DisplayFileName)</h3>
|
||||
<div class="subsectioncontent">
|
||||
#if ($dependency.description)
|
||||
<p><b>Description:</b> $enc.html($dependency.description)<br/></p>
|
||||
@@ -714,7 +721,7 @@ arising out of or in connection with the use of this tool, the analysis performe
|
||||
<div id="content$cnt" class="subsectioncontent standardsubsection hidden">
|
||||
<table class="lined fullwidth" border="0">
|
||||
<tr><th class="left" style="width:10%;">Source</th><th class="left" style="width:20%;">Name</th><th class="left" style="width:70%;">Value</th></tr>
|
||||
#foreach($evidence in $dependency.getEvidenceUsed())
|
||||
#foreach($evidence in $dependency.getEvidenceForDisplay())
|
||||
<tr><td>$enc.html($evidence.getSource())</td><td>$enc.html($evidence.getName())</td><td>$enc.html($evidence.getValue())</td></tr>
|
||||
#end
|
||||
</table>
|
||||
@@ -725,7 +732,7 @@ arising out of or in connection with the use of this tool, the analysis performe
|
||||
<div id="content$cnt" class="subsectioncontent standardsubsection hidden">
|
||||
<ul>
|
||||
#foreach($related in $dependency.getRelatedDependencies())
|
||||
<li>$enc.html($related.FileName)
|
||||
<li>$enc.html($related.DisplayFileName)
|
||||
<ul>
|
||||
<li>File Path: $enc.html($related.FilePath)</li>
|
||||
<li>SHA1: $enc.html($related.Sha1sum)</li>
|
||||
@@ -744,7 +751,7 @@ arising out of or in connection with the use of this tool, the analysis performe
|
||||
#end
|
||||
#end
|
||||
<h4 id="header$cnt" class="subsectionheader white">Suppressed Identifiers</h4>
|
||||
##: <a href="http://web.nvd.nist.gov/view/vuln/search-results?cpe=$enc.url($cpevalue)" target="_blank">$enc.html($cpevalue)</a></h4>
|
||||
##: <a href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($cpevalue)" target="_blank">$enc.html($cpevalue)</a></h4>
|
||||
<div id="content$cnt" class="subsectioncontent standardsubsection">
|
||||
#if ($dependency.getSuppressedIdentifiers().size()==0)
|
||||
<ul><li><b>None</b></li></ul>
|
||||
@@ -796,13 +803,19 @@ arising out of or in connection with the use of this tool, the analysis performe
|
||||
</ul>
|
||||
#end
|
||||
</p>
|
||||
<p>Vulnerable Software & Versions: (<a href="#" onclick="toggleDisplay(this,'.vs$vsctr'); return false;">show all</a>)<ul>
|
||||
<li class="vs$vsctr"><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/search-results?cpe=$enc.url($vuln.matchedCPE)">$enc.html($vuln.matchedCPE)</a> #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end</li>
|
||||
<li class="vs$vsctr">...</li>
|
||||
#foreach($vs in $vuln.getVulnerableSoftware())
|
||||
<li class="vs$vsctr hidden"><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/search-results?cpe=$enc.url($vs.name)">$enc.html($vs.name)</a> #if($vs.hasPreviousVersion()) and all previous versions#end</li>
|
||||
#if ($vuln.getVulnerableSoftware().size()<2)
|
||||
<p>Vulnerable Software & Versions:<ul>
|
||||
git st<li class="vs$vsctr"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vuln.matchedCPE)">$enc.html($vuln.matchedCPE)</a> #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end</li>
|
||||
</ul></p>
|
||||
#else
|
||||
<p>Vulnerable Software & Versions: (<a href="#" onclick="toggleDisplay(this,'.vs$vsctr'); return false;">show all</a>)<ul>
|
||||
<li class="vs$vsctr"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vuln.matchedCPE)">$enc.html($vuln.matchedCPE)</a> #if($vuln.hasMatchedAllPreviousCPE()) and all previous versions#end</li>
|
||||
<li class="vs$vsctr">...</li>
|
||||
#foreach($vs in $vuln.getVulnerableSoftware())
|
||||
<li class="vs$vsctr hidden"><a target="_blank" href="https://web.nvd.nist.gov/view/vuln/search-results?adv_search=true&cves=on&cpe_version=$enc.url($vs.name)">$enc.html($vs.name)</a> #if($vs.hasPreviousVersion()) and all previous versions#end</li>
|
||||
#end
|
||||
</ul></p>
|
||||
#end
|
||||
</ul></p>
|
||||
#end
|
||||
</div>
|
||||
#end
|
||||
|
||||
@@ -222,10 +222,10 @@ arising out of or in connection with the use of this tool, the analysis performe
|
||||
($vuln.cvssScore)
|
||||
<td>#set($cnt=$cnt+1)
|
||||
#if($dependency.getRelatedDependencies().size()>0)<span id="header$cnt" class="expandable collapsedList">#end
|
||||
$enc.html($dependency.FileName)
|
||||
$enc.html($dependency.DisplayFileName)
|
||||
#if($dependency.getRelatedDependencies().size()>0) </span><div id="content$cnt" class="hidden">#end
|
||||
#foreach($related in $dependency.getRelatedDependencies())
|
||||
$enc.html($related.FileName)<br/>
|
||||
$enc.html($related.DisplayFileName)<br/>
|
||||
#end
|
||||
#if($dependency.getRelatedDependencies().size()>0)</div#end
|
||||
</td>
|
||||
|
||||
@@ -36,7 +36,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
<dependencies>
|
||||
#foreach($dependency in $dependencies)
|
||||
<dependency>
|
||||
<fileName>$enc.xml($dependency.FileName)</fileName>
|
||||
<fileName>$enc.xml($dependency.DisplayFileName)</fileName>
|
||||
<filePath>$enc.xml($dependency.FilePath)</filePath>
|
||||
<md5>$enc.xml($dependency.Md5sum)</md5>
|
||||
<sha1>$enc.xml($dependency.Sha1sum)</sha1>
|
||||
@@ -68,7 +68,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
</relatedDependencies>
|
||||
#end
|
||||
<evidenceCollected>
|
||||
#foreach($evidence in $dependency.getEvidenceUsed())
|
||||
#foreach($evidence in $dependency.getEvidenceForDisplay())
|
||||
<evidence>
|
||||
<source>$enc.xml($evidence.getSource())</source>
|
||||
<name>$enc.xml($evidence.getName())</name>
|
||||
|
||||
@@ -32,6 +32,6 @@ public class BaseTest {
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownClass() throws Exception {
|
||||
Settings.cleanup();
|
||||
Settings.cleanup(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,31 +17,78 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.owasp.dependencycheck.BaseTest;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
import org.owasp.dependencycheck.suppression.SuppressionParseException;
|
||||
import org.owasp.dependencycheck.suppression.SuppressionRule;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||
*/
|
||||
public class AbstractSuppressionAnalyzerTest extends BaseTest {
|
||||
|
||||
private AbstractSuppressionAnalyzer instance;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
public void createObjectUnderTest() throws Exception {
|
||||
instance = new AbstractSuppressionAnalyzerImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of getSupportedExtensions method, of class AbstractSuppressionAnalyzer.
|
||||
*/
|
||||
@Test
|
||||
public void testGetSupportedExtensions() {
|
||||
Set<String> result = instance.getSupportedExtensions();
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of getRules method, of class AbstractSuppressionAnalyzer for suppression file declared as URL.
|
||||
*/
|
||||
@Test
|
||||
public void testGetRulesFromSuppressionFileFromURL() throws Exception {
|
||||
setSupressionFileFromURL();
|
||||
instance.initialize();
|
||||
int expCount = 5;
|
||||
List<SuppressionRule> result = instance.getRules();
|
||||
assertTrue(expCount <= result.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of getRules method, of class AbstractSuppressionAnalyzer for suppression file declared as URL.
|
||||
*/
|
||||
@Test
|
||||
public void testGetRulesFromSuppressionFileInClasspath() throws Exception {
|
||||
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "suppressions.xml");
|
||||
instance.initialize();
|
||||
int expCount = 5;
|
||||
List<SuppressionRule> result = instance.getRules();
|
||||
assertTrue(expCount <= result.size());
|
||||
}
|
||||
|
||||
@Test(expected = SuppressionParseException.class)
|
||||
public void testFailureToLocateSuppressionFileAnywhere() throws Exception {
|
||||
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "doesnotexist.xml");
|
||||
instance.initialize();
|
||||
}
|
||||
|
||||
private void setSupressionFileFromURL() throws Exception {
|
||||
try {
|
||||
final String uri = this.getClass().getClassLoader().getResource("suppressions.xml").toURI().toURL().toString();
|
||||
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, uri);
|
||||
@@ -52,37 +99,6 @@ public class AbstractSuppressionAnalyzerTest extends BaseTest {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of getSupportedExtensions method, of class AbstractSuppressionAnalyzer.
|
||||
*/
|
||||
@Test
|
||||
public void testGetSupportedExtensions() {
|
||||
AbstractSuppressionAnalyzer instance = new AbstractSuppressionAnalyzerImpl();
|
||||
Set<String> result = instance.getSupportedExtensions();
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of initialize method, of class AbstractSuppressionAnalyzer.
|
||||
*/
|
||||
@Test
|
||||
public void testInitialize() throws Exception {
|
||||
AbstractSuppressionAnalyzer instance = new AbstractSuppressionAnalyzerImpl();
|
||||
instance.initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of getRules method, of class AbstractSuppressionAnalyzer.
|
||||
*/
|
||||
@Test
|
||||
public void testGetRules() throws Exception {
|
||||
AbstractSuppressionAnalyzer instance = new AbstractSuppressionAnalyzerImpl();
|
||||
instance.initialize();
|
||||
int expCount = 5;
|
||||
List<SuppressionRule> result = instance.getRules();
|
||||
assertEquals(expCount, result.size());
|
||||
}
|
||||
|
||||
public class AbstractSuppressionAnalyzerImpl extends AbstractSuppressionAnalyzer {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -115,16 +115,13 @@ public class CPEAnalyzerIntegrationTest extends AbstractDatabaseTestCase {
|
||||
FalsePositiveAnalyzer fp = new FalsePositiveAnalyzer();
|
||||
fp.analyze(dep, null);
|
||||
|
||||
// for (Identifier i : dep.getIdentifiers()) {
|
||||
// System.out.println(i.getValue());
|
||||
// }
|
||||
if (expResult != null) {
|
||||
Identifier expIdentifier = new Identifier("cpe", expResult, expResult);
|
||||
Assert.assertTrue("Incorrect match: { dep:'" + dep.getFileName() + "' }", dep.getIdentifiers().contains(expIdentifier));
|
||||
} else if (dep.getIdentifiers().isEmpty()) {
|
||||
Assert.assertTrue("Match found when an Identifier should not have been found: { dep:'" + dep.getFileName() + "' }", dep.getIdentifiers().isEmpty());
|
||||
} else {
|
||||
Assert.assertTrue("Match found when an Identifier should not have been found: { dep:'" + dep.getFileName() + "', identifier:'" + dep.getIdentifiers().iterator().next().getValue() + "' }", dep.getIdentifiers().isEmpty());
|
||||
for (Identifier i : dep.getIdentifiers()) {
|
||||
Assert.assertFalse(String.format("%s - found a CPE identifier when should have been none (found '%s')", dep.getFileName(), i.getValue()), "cpe".equals(i.getType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,7 +167,10 @@ public class CPEAnalyzerIntegrationTest extends AbstractDatabaseTestCase {
|
||||
String expResultSpring = "cpe:/a:springsource:spring_framework:2.5.5";
|
||||
String expResultSpring3 = "cpe:/a:vmware:springsource_spring_framework:3.0.0";
|
||||
|
||||
Assert.assertTrue("Apache Common Validator - found an identifier?", commonValidator.getIdentifiers().isEmpty());
|
||||
for (Identifier i : commonValidator.getIdentifiers()) {
|
||||
Assert.assertFalse("Apache Common Validator - found a CPE identifier?", "cpe".equals(i.getType()));
|
||||
}
|
||||
|
||||
Assert.assertTrue("Incorrect match size - struts", struts.getIdentifiers().size() >= 1);
|
||||
Assert.assertTrue("Incorrect match - struts", struts.getIdentifiers().contains(expIdentifier));
|
||||
Assert.assertTrue("Incorrect match size - spring3 - " + spring3.getIdentifiers().size(), spring3.getIdentifiers().size() >= 1);
|
||||
|
||||
@@ -56,6 +56,7 @@ public class FalsePositiveAnalyzerTest {
|
||||
public void testAnalyze() throws Exception {
|
||||
Dependency dependency = new Dependency();
|
||||
dependency.setFileName("pom.xml");
|
||||
dependency.setFilePath("pom.xml");
|
||||
dependency.addIdentifier("cpe", "cpe:/a:file:file:1.2.1", "http://some.org/url");
|
||||
Engine engine = null;
|
||||
FalsePositiveAnalyzer instance = new FalsePositiveAnalyzer();
|
||||
|
||||
@@ -61,19 +61,26 @@ public class VulnerabilitySuppressionAnalyzerIntegrationTest extends AbstractDat
|
||||
@Test
|
||||
public void testAnalyze() throws Exception {
|
||||
|
||||
File file = new File(this.getClass().getClassLoader().getResource("FileHelpers.2.0.0.0.nupkg").getPath());
|
||||
File suppression = new File(this.getClass().getClassLoader().getResource("FileHelpers.2.0.0.0.suppression.xml").getPath());
|
||||
File file = new File(this.getClass().getClassLoader().getResource("commons-fileupload-1.2.1.jar").getPath());
|
||||
File suppression = new File(this.getClass().getClassLoader().getResource("commons-fileupload-1.2.1.suppression.xml").getPath());
|
||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
|
||||
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false);
|
||||
Engine engine = new Engine();
|
||||
engine.scan(file);
|
||||
engine.analyzeDependencies();
|
||||
Dependency dependency = getDependency(engine, file);
|
||||
assertTrue(dependency.getVulnerabilities().size() > 0);
|
||||
int cveSize = dependency.getVulnerabilities().size();
|
||||
int cpeSize = dependency.getIdentifiers().size();
|
||||
assertTrue(cveSize > 0);
|
||||
assertTrue(cpeSize > 0);
|
||||
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppression.getAbsolutePath());
|
||||
VulnerabilitySuppressionAnalyzer instance = new VulnerabilitySuppressionAnalyzer();
|
||||
instance.initialize();
|
||||
instance.analyze(dependency, engine);
|
||||
assertTrue(dependency.getVulnerabilities().size() == 0);
|
||||
cveSize = cveSize > 1 ? cveSize - 2 : 0;
|
||||
cpeSize = cpeSize > 0 ? cpeSize - 1 : 0;
|
||||
assertTrue(dependency.getVulnerabilities().size() == cveSize);
|
||||
assertTrue(dependency.getIdentifiers().size() == cpeSize);
|
||||
engine.cleanup();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,12 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck.data.update;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Calendar;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.owasp.dependencycheck.BaseTest;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -26,6 +30,32 @@ import org.owasp.dependencycheck.BaseTest;
|
||||
*/
|
||||
public class NvdCveUpdaterIntegrationTest extends BaseTest {
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
int year = Calendar.getInstance().get(Calendar.YEAR);
|
||||
if (year <= 2014) {
|
||||
File f = new File(NvdCveUpdaterIntegrationTest.class.getClassLoader().getResource("nvdcve-2.0-2014.xml").getPath());
|
||||
String baseURL = f.toURI().toURL().toString();
|
||||
String modified12 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-modified.xml");
|
||||
String modified20 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-2.0-modified.xml");
|
||||
String full12 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-%d.xml");
|
||||
String full20 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-2.0-%d.xml");
|
||||
// cve.url-1.2.modified=http://nvd.nist.gov/download/nvdcve-modified.xml
|
||||
// cve.url-2.0.modified=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
|
||||
// cve.startyear=2014
|
||||
// cve.url-2.0.base=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
|
||||
// cve.url-1.2.base=http://nvd.nist.gov/download/nvdcve-%d.xml
|
||||
|
||||
Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, modified12);
|
||||
Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, modified20);
|
||||
Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, full12);
|
||||
Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, full20);
|
||||
Settings.setString(Settings.KEYS.CVE_START_YEAR, "2014");
|
||||
} else {
|
||||
System.err.println("Consider updating the local data files to make the NvdCveUpdaterIntegrationTest perform faster");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of update method, of class NvdCveUpdater.
|
||||
*/
|
||||
|
||||
@@ -67,16 +67,16 @@ public class StandardUpdateIntegrationTest extends BaseTest {
|
||||
result = instance.withinRange(lastRun, current, range);
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of update method, of class StandardUpdate.
|
||||
*/
|
||||
@Test
|
||||
public void testUpdate() throws Exception {
|
||||
StandardUpdate instance = getStandardUpdateTask();
|
||||
instance.update();
|
||||
//TODO make this an actual test
|
||||
}
|
||||
// test removed as it is duplicative of the EngineIntegrationTest and the NvdCveUpdaterIntergraionTest
|
||||
// /**
|
||||
// * Test of update method, of class StandardUpdate.
|
||||
// */
|
||||
// @Test
|
||||
// public void testUpdate() throws Exception {
|
||||
// StandardUpdate instance = getStandardUpdateTask();
|
||||
// instance.update();
|
||||
// //TODO make this an actual test
|
||||
// }
|
||||
|
||||
/**
|
||||
* Test of updatesNeeded method, of class StandardUpdate.
|
||||
|
||||
@@ -339,55 +339,70 @@ public class SuppressionRuleTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of cpeMatches method, of class SuppressionRule.
|
||||
* Test of identifierMatches method, of class SuppressionRule.
|
||||
*/
|
||||
@Test
|
||||
public void testCpeMatches() {
|
||||
Identifier identifier = new Identifier("cwe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
|
||||
Identifier identifier = new Identifier("cpe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
|
||||
|
||||
PropertyType cpe = new PropertyType();
|
||||
cpe.setValue("cpe:/a:microsoft:.net_framework:4.5");
|
||||
|
||||
SuppressionRule instance = new SuppressionRule();
|
||||
boolean expResult = true;
|
||||
boolean result = instance.cpeMatches(cpe, identifier);
|
||||
boolean result = instance.identifierMatches("cpe", cpe, identifier);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
cpe.setValue("cpe:/a:microsoft:.net_framework:4.0");
|
||||
expResult = false;
|
||||
result = instance.cpeMatches(cpe, identifier);
|
||||
result = instance.identifierMatches("cpe", cpe, identifier);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
cpe.setValue("CPE:/a:microsoft:.net_framework:4.5");
|
||||
cpe.setCaseSensitive(true);
|
||||
expResult = false;
|
||||
result = instance.cpeMatches(cpe, identifier);
|
||||
result = instance.identifierMatches("cpe", cpe, identifier);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
cpe.setValue("cpe:/a:microsoft:.net_framework");
|
||||
cpe.setCaseSensitive(false);
|
||||
expResult = true;
|
||||
result = instance.cpeMatches(cpe, identifier);
|
||||
result = instance.identifierMatches("cpe", cpe, identifier);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
cpe.setValue("cpe:/a:microsoft:.*");
|
||||
cpe.setRegex(true);
|
||||
expResult = true;
|
||||
result = instance.cpeMatches(cpe, identifier);
|
||||
result = instance.identifierMatches("cpe", cpe, identifier);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
cpe.setValue("CPE:/a:microsoft:.*");
|
||||
cpe.setRegex(true);
|
||||
cpe.setCaseSensitive(true);
|
||||
expResult = false;
|
||||
result = instance.cpeMatches(cpe, identifier);
|
||||
result = instance.identifierMatches("cpe", cpe, identifier);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
cpe.setValue("cpe:/a:apache:.*");
|
||||
cpe.setRegex(true);
|
||||
cpe.setCaseSensitive(false);
|
||||
expResult = false;
|
||||
result = instance.cpeMatches(cpe, identifier);
|
||||
result = instance.identifierMatches("cpe", cpe, identifier);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
identifier = new Identifier("maven", "org.springframework:spring-core:2.5.5", "https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.springframework&a=spring-core&v=2.5.5&e=jar");
|
||||
cpe.setValue("org.springframework:spring-core:2.5.5");
|
||||
cpe.setRegex(false);
|
||||
cpe.setCaseSensitive(false);
|
||||
expResult = true;
|
||||
result = instance.identifierMatches("maven", cpe, identifier);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
cpe.setValue("org\\.springframework\\.security:spring.*");
|
||||
cpe.setRegex(true);
|
||||
cpe.setCaseSensitive(false);
|
||||
expResult = false;
|
||||
result = instance.identifierMatches("maven", cpe, identifier);
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
@@ -398,7 +413,7 @@ public class SuppressionRuleTest {
|
||||
public void testProcess() {
|
||||
File struts = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath());
|
||||
Dependency dependency = new Dependency(struts);
|
||||
dependency.addIdentifier("cwe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
|
||||
dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
|
||||
String sha1 = dependency.getSha1sum();
|
||||
dependency.setSha1sum("384FAA82E193D4E4B0546059CA09572654BC3970");
|
||||
Vulnerability v = createVulnerability();
|
||||
@@ -455,9 +470,9 @@ public class SuppressionRuleTest {
|
||||
assertTrue(dependency.getIdentifiers().isEmpty());
|
||||
assertTrue(dependency.getSuppressedIdentifiers().size() == 1);
|
||||
|
||||
dependency.addIdentifier("cwe", "cpe:/a:microsoft:.net_framework:4.0", "some url not needed for this test");
|
||||
dependency.addIdentifier("cwe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
|
||||
dependency.addIdentifier("cwe", "cpe:/a:microsoft:.net_framework:5.0", "some url not needed for this test");
|
||||
dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:4.0", "some url not needed for this test");
|
||||
dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:4.5", "some url not needed for this test");
|
||||
dependency.addIdentifier("cpe", "cpe:/a:microsoft:.net_framework:5.0", "some url not needed for this test");
|
||||
pt = new PropertyType();
|
||||
pt.setValue("cpe:/a:microsoft:.net_framework");
|
||||
instance.addCpe(pt);
|
||||
@@ -467,6 +482,43 @@ public class SuppressionRuleTest {
|
||||
assertTrue(dependency.getSuppressedIdentifiers().size() == 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of process method, of class SuppressionRule.
|
||||
*/
|
||||
@Test
|
||||
public void testProcessGAV() {
|
||||
File spring = new File(this.getClass().getClassLoader().getResource("spring-security-web-3.0.0.RELEASE.jar").getPath());
|
||||
Dependency dependency = new Dependency(spring);
|
||||
dependency.addIdentifier("cpe", "cpe:/a:vmware:springsource_spring_framework:3.0.0", "some url not needed for this test");
|
||||
dependency.addIdentifier("cpe", "cpe:/a:springsource:spring_framework:3.0.0", "some url not needed for this test");
|
||||
dependency.addIdentifier("cpe", "cpe:/a:mod_security:mod_security:3.0.0", "some url not needed for this test");
|
||||
dependency.addIdentifier("cpe", "cpe:/a:vmware:springsource_spring_security:3.0.0", "some url not needed for this test");
|
||||
dependency.addIdentifier("maven", "org.springframework.security:spring-security-web:3.0.0.RELEASE", "some url not needed for this test");
|
||||
|
||||
//cpe
|
||||
SuppressionRule instance = new SuppressionRule();
|
||||
PropertyType pt = new PropertyType();
|
||||
|
||||
pt.setValue("org\\.springframework\\.security:spring.*");
|
||||
pt.setRegex(true);
|
||||
pt.setCaseSensitive(false);
|
||||
instance.setGav(pt);
|
||||
|
||||
pt = new PropertyType();
|
||||
pt.setValue("cpe:/a:mod_security:mod_security");
|
||||
instance.addCpe(pt);
|
||||
pt = new PropertyType();
|
||||
pt.setValue("cpe:/a:springsource:spring_framework");
|
||||
instance.addCpe(pt);
|
||||
pt = new PropertyType();
|
||||
pt.setValue("cpe:/a:vmware:springsource_spring_framework");
|
||||
instance.addCpe(pt);
|
||||
|
||||
instance.process(dependency);
|
||||
assertEquals(2, dependency.getIdentifiers().size());
|
||||
|
||||
}
|
||||
|
||||
private Vulnerability createVulnerability() {
|
||||
Vulnerability v = new Vulnerability();
|
||||
v.setCwe("CWE-287 Improper Authentication");
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<suppressions xmlns="https://www.owasp.org/index.php/OWASP_Dependency_Check_Suppression">
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: FileHelpers.2.0.0.0.nupkg
|
||||
]]></notes>
|
||||
<sha1>30FB37D6163CF16E3BA740343BECDD14D5457619</sha1>
|
||||
<cve>CVE-2007-1536</cve>
|
||||
</suppress>
|
||||
</suppressions>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<suppressions xmlns="https://www.owasp.org/index.php/OWASP_Dependency_Check_Suppression">
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: commons-fileupload-1.2.1.jar
|
||||
]]></notes>
|
||||
<sha1>384FAA82E193D4E4B0546059CA09572654BC3970</sha1>
|
||||
<cpe>cpe:/a:apache:commons_fileupload:1.2.1</cpe>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: commons-fileupload-1.2.1.jar
|
||||
]]></notes>
|
||||
<sha1>384FAA82E193D4E4B0546059CA09572654BC3970</sha1>
|
||||
<cve>CVE-2014-0050</cve>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
file name: commons-fileupload-1.2.1.jar
|
||||
]]></notes>
|
||||
<sha1>384FAA82E193D4E4B0546059CA09572654BC3970</sha1>
|
||||
<cve>CVE-2013-0248</cve>
|
||||
</suppress>
|
||||
</suppressions>
|
||||
12297
dependency-check-core/src/test/resources/nvdcve-modified.xml
Normal file
12297
dependency-check-core/src/test/resources/nvdcve-modified.xml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.2.0</version>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.owasp</groupId>
|
||||
|
||||
@@ -15,7 +15,6 @@ limitations under the License.
|
||||
|
||||
Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<url>http://maven.apache.org</url>
|
||||
@@ -23,7 +22,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.2.0</version>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dependency-check-maven</artifactId>
|
||||
@@ -277,6 +276,11 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
<artifactId>dependency-check-core</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-utils</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-plugin-api</artifactId>
|
||||
|
||||
@@ -147,15 +147,6 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||
@Parameter(property = "externalReport", defaultValue = "false", required = true)
|
||||
private boolean externalReport = false;
|
||||
/**
|
||||
* The Proxy URL.
|
||||
*
|
||||
* @deprecated Please use mavenSettings instead
|
||||
*/
|
||||
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||
@Parameter(property = "proxyUrl", defaultValue = "", required = false)
|
||||
@Deprecated
|
||||
private String proxyUrl = null;
|
||||
|
||||
/**
|
||||
* The maven settings.
|
||||
@@ -171,33 +162,6 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
@Parameter(property = "mavenSettingsProxyId", required = false)
|
||||
private String mavenSettingsProxyId;
|
||||
|
||||
/**
|
||||
* The Proxy Port.
|
||||
*
|
||||
* @deprecated Please use mavenSettings instead
|
||||
*/
|
||||
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||
@Parameter(property = "proxyPort", defaultValue = "", required = false)
|
||||
@Deprecated
|
||||
private String proxyPort = null;
|
||||
/**
|
||||
* The Proxy username.
|
||||
*
|
||||
* @deprecated Please use mavenSettings instead
|
||||
*/
|
||||
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||
@Parameter(property = "proxyUsername", defaultValue = "", required = false)
|
||||
@Deprecated
|
||||
private String proxyUsername = null;
|
||||
/**
|
||||
* The Proxy password.
|
||||
*
|
||||
* @deprecated Please use mavenSettings instead
|
||||
*/
|
||||
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||
@Parameter(property = "proxyPassword", defaultValue = "", required = false)
|
||||
@Deprecated
|
||||
private String proxyPassword = null;
|
||||
/**
|
||||
* The Connection Timeout.
|
||||
*/
|
||||
@@ -348,6 +312,16 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
@Parameter(property = "pathToMono", defaultValue = "", required = false)
|
||||
private String pathToMono;
|
||||
|
||||
/**
|
||||
* The Proxy URL.
|
||||
*
|
||||
* @deprecated Please use mavenSettings instead
|
||||
*/
|
||||
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||
@Parameter(property = "proxyUrl", defaultValue = "", required = false)
|
||||
@Deprecated
|
||||
private String proxyUrl = null;
|
||||
|
||||
// </editor-fold>
|
||||
/**
|
||||
* Executes the Dependency-Check on the dependent libraries.
|
||||
@@ -613,7 +587,8 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
*/
|
||||
private int writeSiteReportDependencyEvidenceUsed(Dependency d, int collapsibleHeaderCount, Sink sink) {
|
||||
int cnt = collapsibleHeaderCount;
|
||||
if (d.getEvidenceUsed() != null && d.getEvidenceUsed().size() > 0) {
|
||||
final Set<Evidence> evidence = d.getEvidenceForDisplay();
|
||||
if (evidence != null && evidence.size() > 0) {
|
||||
cnt += 1;
|
||||
sink.sectionTitle4();
|
||||
sink.rawText("Evidence Collected <a href=\"javascript:toggleElement(this, 'evidence" + cnt + "')\">[+]</a>");
|
||||
@@ -625,7 +600,7 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
writeTableHeaderCell(sink, "Name");
|
||||
writeTableHeaderCell(sink, "Value");
|
||||
sink.tableRow_();
|
||||
for (Evidence e : d.getEvidenceUsed()) {
|
||||
for (Evidence e : evidence) {
|
||||
sink.tableRow();
|
||||
writeTableCell(sink, e.getSource());
|
||||
writeTableCell(sink, e.getName());
|
||||
@@ -776,12 +751,12 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* Returns the maven settings proxy url.
|
||||
* Returns the maven settings proxy server.
|
||||
*
|
||||
* @param proxy the maven proxy
|
||||
* @return the proxy url
|
||||
*/
|
||||
private String getMavenSettingsProxyUrl(Proxy proxy) {
|
||||
private String getMavenSettingsProxyServer(Proxy proxy) {
|
||||
return new StringBuilder(proxy.getProtocol()).append("://").append(proxy.getHost()).toString();
|
||||
}
|
||||
|
||||
@@ -835,9 +810,13 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
|
||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
|
||||
|
||||
if (proxyUrl != null && !proxyUrl.isEmpty()) {
|
||||
logger.warning("Deprecated configuration detected, proxyUrl will be ignored; use the maven settings to configure the proxy instead");
|
||||
}
|
||||
|
||||
final Proxy proxy = getMavenProxy();
|
||||
if (proxy != null) {
|
||||
Settings.setString(Settings.KEYS.PROXY_URL, getMavenSettingsProxyUrl(proxy));
|
||||
Settings.setString(Settings.KEYS.PROXY_SERVER, getMavenSettingsProxyServer(proxy));
|
||||
Settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(proxy.getPort()));
|
||||
final String userName = proxy.getUsername();
|
||||
final String password = proxy.getPassword();
|
||||
@@ -847,18 +826,6 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
}
|
||||
}
|
||||
|
||||
if (proxyUrl != null && !proxyUrl.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.PROXY_URL, proxyUrl);
|
||||
}
|
||||
if (proxyPort != null && !proxyPort.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort);
|
||||
}
|
||||
if (proxyUsername != null && !proxyUsername.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.PROXY_USERNAME, proxyUsername);
|
||||
}
|
||||
if (proxyPassword != null && !proxyPassword.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.PROXY_PASSWORD, proxyPassword);
|
||||
}
|
||||
if (connectionTimeout != null && !connectionTimeout.isEmpty()) {
|
||||
Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
|
||||
}
|
||||
@@ -952,7 +919,7 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
"Unable to connect to the dependency-check database; analysis has stopped");
|
||||
logger.log(Level.FINE, "", ex);
|
||||
} finally {
|
||||
Settings.cleanup();
|
||||
Settings.cleanup(true);
|
||||
if (engine != null) {
|
||||
engine.cleanup();
|
||||
}
|
||||
@@ -993,7 +960,7 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
||||
"Unable to connect to the dependency-check database; analysis has stopped");
|
||||
logger.log(Level.FINE, "", ex);
|
||||
} finally {
|
||||
Settings.cleanup();
|
||||
Settings.cleanup(true);
|
||||
if (engine != null) {
|
||||
engine.cleanup();
|
||||
}
|
||||
|
||||
@@ -55,17 +55,6 @@ databaseUser | The username used when connecting to the database.
|
||||
databasePassword | The password used when connecting to the database. |
|
||||
|
||||
|
||||
Deprecated Configuration
|
||||
Proxy Configuration
|
||||
====================
|
||||
The following properties have been deprecated. These can still be set in
|
||||
the dependency-check-maven plugin's configuration. However, future versions
|
||||
will remove these properties. Instead using these properties you should
|
||||
use [Maven's settings](https://maven.apache.org/settings.html#Proxies) to
|
||||
configure a proxy.
|
||||
|
||||
Property | Description | Default Value
|
||||
---------------------|------------------------------------|------------------
|
||||
proxyUrl | The Proxy URL. |
|
||||
proxyPort | The Proxy Port. |
|
||||
proxyUsername | Defines the proxy user name. |
|
||||
proxyPassword | Defines the proxy password. |
|
||||
Use [Maven's settings](https://maven.apache.org/settings.html#Proxies) to configure a proxy server.
|
||||
|
||||
280
dependency-check-utils/pom.xml
Normal file
280
dependency-check-utils/pom.xml
Normal file
@@ -0,0 +1,280 @@
|
||||
<!--
|
||||
This file is part of dependency-check-utils.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Copyright (c) 2014 - Jeremy Long. All Rights Reserved.
|
||||
-->
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dependency-check-utils</artifactId>
|
||||
<name>Dependency-Check Utils</name>
|
||||
<description>Dependency-check-utils a collection of common utlity classes used within dependency-check.</description>
|
||||
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
|
||||
<distributionManagement>
|
||||
<site>
|
||||
<id>github-pages-site</id>
|
||||
<name>Deployment through GitHub's site deployment plugin</name>
|
||||
<url>${basedir}/../target/site/${project.version}/dependency-check-ant</url>
|
||||
</site>
|
||||
</distributionManagement>
|
||||
<!-- end copy -->
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
<configuration>
|
||||
<instrumentation>
|
||||
<ignoreTrivial>true</ignoreTrivial>
|
||||
</instrumentation>
|
||||
<check>
|
||||
<branchRate>85</branchRate>
|
||||
<lineRate>85</lineRate>
|
||||
<haltOnFailure>false</haltOnFailure>
|
||||
<totalBranchRate>85</totalBranchRate>
|
||||
<totalLineRate>85</totalLineRate>
|
||||
<packageLineRate>85</packageLineRate>
|
||||
<packageBranchRate>85</packageBranchRate>
|
||||
<regexes>
|
||||
<regex>
|
||||
<pattern>.*\$.*</pattern>
|
||||
<branchRate>0</branchRate>
|
||||
<lineRate>0</lineRate>
|
||||
</regex>
|
||||
</regexes>
|
||||
</check>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.16</version>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>temp.directory</name>
|
||||
<value>${project.build.directory}/temp</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
<excludes>
|
||||
<exclude>**/*IntegrationTest.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>2.16</version>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>temp.directory</name>
|
||||
<value>${project.build.directory}/temp</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
<includes>
|
||||
<include>**/*IntegrationTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<showDeprecation>false</showDeprecation>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-site-plugin</artifactId>
|
||||
<version>3.3</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.doxia</groupId>
|
||||
<artifactId>doxia-module-markdown</artifactId>
|
||||
<version>1.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
<skipDeploy>true</skipDeploy>
|
||||
<reportPlugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||
<version>2.7</version>
|
||||
<reportSets>
|
||||
<reportSet>
|
||||
<reports>
|
||||
<report>index</report>
|
||||
<report>summary</report>
|
||||
<report>license</report>
|
||||
<report>help</report>
|
||||
</reports>
|
||||
</reportSet>
|
||||
</reportSets>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.9.1</version>
|
||||
<reportSets>
|
||||
<reportSet>
|
||||
<id>default</id>
|
||||
<reports>
|
||||
<report>javadoc</report>
|
||||
</reports>
|
||||
</reportSet>
|
||||
</reportSets>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>versions-maven-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
<reportSets>
|
||||
<reportSet>
|
||||
<reports>
|
||||
<report>dependency-updates-report</report>
|
||||
<report>plugin-updates-report</report>
|
||||
</reports>
|
||||
</reportSet>
|
||||
</reportSets>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jxr-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-report-plugin</artifactId>
|
||||
<version>2.16</version>
|
||||
<reportSets>
|
||||
<reportSet>
|
||||
<reports>
|
||||
<report>report-only</report>
|
||||
</reports>
|
||||
</reportSet>
|
||||
</reportSets>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>taglist-maven-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<configuration>
|
||||
<tagListOptions>
|
||||
<tagClasses>
|
||||
<tagClass>
|
||||
<displayName>Todo Work</displayName>
|
||||
<tags>
|
||||
<tag>
|
||||
<matchString>todo</matchString>
|
||||
<matchType>ignoreCase</matchType>
|
||||
</tag>
|
||||
<tag>
|
||||
<matchString>FIXME</matchString>
|
||||
<matchType>exact</matchType>
|
||||
</tag>
|
||||
</tags>
|
||||
</tagClass>
|
||||
</tagClasses>
|
||||
</tagListOptions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>2.11</version>
|
||||
<configuration>
|
||||
<enableRulesSummary>false</enableRulesSummary>
|
||||
<configLocation>${basedir}/../src/main/config/checkstyle-checks.xml</configLocation>
|
||||
<headerLocation>${basedir}/../src/main/config/checkstyle-header.txt</headerLocation>
|
||||
<suppressionsLocation>${basedir}/../src/main/config/checkstyle-suppressions.xml</suppressionsLocation>
|
||||
<suppressionsFileExpression>checkstyle.suppressions.file</suppressionsFileExpression>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-pmd-plugin</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<configuration>
|
||||
<targetJdk>1.6</targetJdk>
|
||||
<linkXref>true</linkXref>
|
||||
<sourceEncoding>utf-8</sourceEncoding>
|
||||
<rulesets>
|
||||
<ruleset>../src/main/config/dcrules.xml</ruleset>
|
||||
<ruleset>/rulesets/java/basic.xml</ruleset>
|
||||
<ruleset>/rulesets/java/imports.xml</ruleset>
|
||||
<ruleset>/rulesets/java/unusedcode.xml</ruleset>
|
||||
</rulesets>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>findbugs-maven-plugin</artifactId>
|
||||
<version>2.5.3</version>
|
||||
</plugin>
|
||||
</reportPlugins>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -166,7 +166,7 @@ public final class Downloader {
|
||||
try {
|
||||
lastModifiedFile = new File(url.toURI());
|
||||
} catch (URISyntaxException ex) {
|
||||
final String msg = String.format("Unable to locate '%s'; is the cve.url-2.0.modified property set correctly?", url.toString());
|
||||
final String msg = String.format("Unable to locate '%s'", url.toString());
|
||||
throw new DownloadFailedException(msg);
|
||||
}
|
||||
timestamp = lastModifiedFile.lastModified();
|
||||
@@ -176,7 +176,12 @@ public final class Downloader {
|
||||
conn = URLConnectionFactory.createHttpURLConnection(url);
|
||||
conn.setRequestMethod("HEAD");
|
||||
conn.connect();
|
||||
timestamp = conn.getLastModified();
|
||||
final int t = conn.getResponseCode();
|
||||
if (t >= 200 && t < 300) {
|
||||
timestamp = conn.getLastModified();
|
||||
} else {
|
||||
throw new DownloadFailedException("HEAD request returned a non-200 status code");
|
||||
}
|
||||
} catch (URLConnectionFailureException ex) {
|
||||
throw new DownloadFailedException("Error creating URL Connection for HTTP HEAD request.", ex);
|
||||
} catch (IOException ex) {
|
||||
@@ -17,21 +17,13 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck.utils;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
|
||||
/**
|
||||
* A collection of utilities for processing information about files.
|
||||
@@ -54,11 +46,6 @@ public final class FileUtils {
|
||||
*/
|
||||
private static final String BIT_BUCKET_WIN = "NUL";
|
||||
|
||||
/**
|
||||
* The buffer size to use when extracting files from the archive.
|
||||
*/
|
||||
private static final int BUFFER_SIZE = 4096;
|
||||
|
||||
/**
|
||||
* Private constructor for a utility class.
|
||||
*/
|
||||
@@ -155,99 +142,6 @@ public final class FileUtils {
|
||||
return jarPath.getParentFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the contents of an archive into the specified directory.
|
||||
*
|
||||
* @param archive an archive file such as a WAR or EAR
|
||||
* @param extractTo a directory to extract the contents to
|
||||
* @throws ExtractionException thrown if an exception occurs while extracting the files
|
||||
*/
|
||||
public static void extractFiles(File archive, File extractTo) throws ExtractionException {
|
||||
extractFiles(archive, extractTo, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the contents of an archive into the specified directory. The files are only extracted if they are
|
||||
* supported by the analyzers loaded into the specified engine. If the engine is specified as null then all files
|
||||
* are extracted.
|
||||
*
|
||||
* @param archive an archive file such as a WAR or EAR
|
||||
* @param extractTo a directory to extract the contents to
|
||||
* @param engine the scanning engine
|
||||
* @throws ExtractionException thrown if there is an error extracting the files
|
||||
*/
|
||||
public static void extractFiles(File archive, File extractTo, Engine engine) throws ExtractionException {
|
||||
if (archive == null || extractTo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
FileInputStream fis = null;
|
||||
ZipInputStream zis = null;
|
||||
|
||||
try {
|
||||
fis = new FileInputStream(archive);
|
||||
} catch (FileNotFoundException ex) {
|
||||
LOGGER.log(Level.FINE, null, ex);
|
||||
throw new ExtractionException("Archive file was not found.", ex);
|
||||
}
|
||||
zis = new ZipInputStream(new BufferedInputStream(fis));
|
||||
ZipEntry entry;
|
||||
try {
|
||||
while ((entry = zis.getNextEntry()) != null) {
|
||||
if (entry.isDirectory()) {
|
||||
final File d = new File(extractTo, entry.getName());
|
||||
if (!d.exists() && !d.mkdirs()) {
|
||||
final String msg = String.format("Unable to create '%s'.", d.getAbsolutePath());
|
||||
throw new ExtractionException(msg);
|
||||
}
|
||||
} else {
|
||||
final File file = new File(extractTo, entry.getName());
|
||||
final String ext = getFileExtension(file.getName());
|
||||
if (engine == null || engine.supportsExtension(ext)) {
|
||||
BufferedOutputStream bos = null;
|
||||
FileOutputStream fos;
|
||||
try {
|
||||
fos = new FileOutputStream(file);
|
||||
bos = new BufferedOutputStream(fos, BUFFER_SIZE);
|
||||
int count;
|
||||
final byte data[] = new byte[BUFFER_SIZE];
|
||||
while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) {
|
||||
bos.write(data, 0, count);
|
||||
}
|
||||
bos.flush();
|
||||
} catch (FileNotFoundException ex) {
|
||||
LOGGER.log(Level.FINE, null, ex);
|
||||
final String msg = String.format("Unable to find file '%s'.", file.getName());
|
||||
throw new ExtractionException(msg, ex);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.FINE, null, ex);
|
||||
final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
|
||||
throw new ExtractionException(msg, ex);
|
||||
} finally {
|
||||
if (bos != null) {
|
||||
try {
|
||||
bos.close();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.FINEST, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
final String msg = String.format("Exception reading archive '%s'.", archive.getName());
|
||||
LOGGER.log(Level.FINE, msg, ex);
|
||||
throw new ExtractionException(msg, ex);
|
||||
} finally {
|
||||
try {
|
||||
zis.close();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.FINEST, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bit bucket for the OS. '/dev/null' for Unix and 'NUL' for Windows
|
||||
*
|
||||
@@ -110,9 +110,16 @@ public final class Settings {
|
||||
*/
|
||||
public static final String CVE_SCHEMA_2_0 = "cve.url-2.0.base";
|
||||
/**
|
||||
* The properties key for the proxy url.
|
||||
* The properties key for the proxy server.
|
||||
*
|
||||
* @deprecated use {@link org.owasp.dependencycheck.utils.Settings.KEYS#PROXY_SERVER} instead.
|
||||
*/
|
||||
public static final String PROXY_URL = "proxy.url";
|
||||
@Deprecated
|
||||
public static final String PROXY_URL = "proxy.server";
|
||||
/**
|
||||
* The properties key for the proxy server.
|
||||
*/
|
||||
public static final String PROXY_SERVER = "proxy.server";
|
||||
/**
|
||||
* The properties key for the proxy port - this must be an integer value.
|
||||
*/
|
||||
@@ -215,12 +222,14 @@ public final class Settings {
|
||||
|
||||
/**
|
||||
* Private constructor for the Settings class. This class loads the properties files.
|
||||
*
|
||||
* @param propertiesFilePath the path to the base properties file to load
|
||||
*/
|
||||
private Settings() {
|
||||
private Settings(String propertiesFilePath) {
|
||||
InputStream in = null;
|
||||
props = new Properties();
|
||||
try {
|
||||
in = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
|
||||
in = this.getClass().getClassLoader().getResourceAsStream(propertiesFilePath);
|
||||
props.load(in);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Unable to load default settings.");
|
||||
@@ -242,14 +251,34 @@ public final class Settings {
|
||||
* However, you must also call Settings.cleanup() to properly release resources.
|
||||
*/
|
||||
public static void initialize() {
|
||||
localSettings.set(new Settings());
|
||||
localSettings.set(new Settings(PROPERTIES_FILE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the thread local settings object. Note, to use the settings object you must call this method.
|
||||
* However, you must also call Settings.cleanup() to properly release resources.
|
||||
*
|
||||
* @param propertiesFilePath the path to the base properties file to load
|
||||
*/
|
||||
public static void initialize(String propertiesFilePath) {
|
||||
localSettings.set(new Settings(propertiesFilePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up resources to prevent memory leaks.
|
||||
*
|
||||
*/
|
||||
public static void cleanup() {
|
||||
if (tempDirectory != null && tempDirectory.exists()) {
|
||||
cleanup(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up resources to prevent memory leaks.
|
||||
*
|
||||
* @param deleteTemporary flag indicating whether any temporary directories generated should be removed
|
||||
*/
|
||||
public static void cleanup(boolean deleteTemporary) {
|
||||
if (deleteTemporary && tempDirectory != null && tempDirectory.exists()) {
|
||||
FileUtils.delete(tempDirectory);
|
||||
}
|
||||
try {
|
||||
@@ -51,7 +51,7 @@ public final class URLConnectionFactory {
|
||||
public static HttpURLConnection createHttpURLConnection(URL url) throws URLConnectionFailureException {
|
||||
HttpURLConnection conn = null;
|
||||
Proxy proxy = null;
|
||||
final String proxyUrl = Settings.getString(Settings.KEYS.PROXY_URL);
|
||||
final String proxyUrl = Settings.getString(Settings.KEYS.PROXY_SERVER);
|
||||
try {
|
||||
if (proxyUrl != null) {
|
||||
final int proxyPort = Settings.getInt(Settings.KEYS.PROXY_PORT);
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* <html>
|
||||
* <head>
|
||||
* <title>org.owasp.dependencycheck.utils</title>
|
||||
* </head>
|
||||
* <body>
|
||||
* Includes various utility classes such as a Settings wrapper, utilities to make URL Connections, etc.
|
||||
* </body>
|
||||
* </html>
|
||||
*/
|
||||
package org.owasp.dependencycheck.utils;
|
||||
30
dependency-check-utils/src/site/site.xml
Normal file
30
dependency-check-utils/src/site/site.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!--
|
||||
This file is part of dependency-check-ant.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Copyright (c) 2014 Jeremy Long. All Rights Reserved.
|
||||
-->
|
||||
<project name="dependency-check-ant">
|
||||
<bannerLeft>
|
||||
<name>dependency-check-utils</name>
|
||||
</bannerLeft>
|
||||
<body>
|
||||
<breadcrumbs>
|
||||
<item name="dependency-check" href="../index.html"/>
|
||||
</breadcrumbs>
|
||||
<menu ref="Project Documentation" />
|
||||
<menu ref="reports" />
|
||||
</body>
|
||||
</project>
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2014 OWASP.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.owasp.dependencycheck.utils;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||
*/
|
||||
public class BaseTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpClass() throws Exception {
|
||||
Settings.initialize();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownClass() throws Exception {
|
||||
Settings.cleanup(true);
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,6 @@ import java.io.File;
|
||||
import java.net.URL;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
import org.owasp.dependencycheck.BaseTest;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -39,7 +38,7 @@ public class DownloaderIntegrationTest extends BaseTest {
|
||||
|
||||
// Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, "1000");
|
||||
// Settings.setString(Settings.KEYS.PROXY_PORT, "8080");
|
||||
// Settings.setString(Settings.KEYS.PROXY_URL, "127.0.0.1");
|
||||
// Settings.setString(Settings.KEYS.PROXY_SERVER, "127.0.0.1");
|
||||
URL url = new URL(Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL));
|
||||
File outputPath = new File("target/downloaded_cve.xml");
|
||||
Downloader.fetchFile(url, outputPath);
|
||||
@@ -19,12 +19,9 @@ package org.owasp.dependencycheck.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.owasp.dependencycheck.utils.Downloader;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -32,25 +29,9 @@ import org.junit.Test;
|
||||
*/
|
||||
public class DownloaderTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpClass() throws Exception {
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownClass() throws Exception {
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLastModified_file() throws Exception {
|
||||
File f = new File("target/test-classes/nvdcve-2.0-2012.xml");
|
||||
File f = new File("target/test-classes/dependencycheck.properties");
|
||||
URL url = new URL("file:///" + f.getCanonicalPath());
|
||||
long timestamp = Downloader.getLastModified(url);
|
||||
assertTrue("timestamp equal to zero?", timestamp > 0);
|
||||
@@ -23,7 +23,6 @@ import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import org.junit.Test;
|
||||
import org.owasp.dependencycheck.BaseTest;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -22,7 +22,6 @@ import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.owasp.dependencycheck.BaseTest;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -0,0 +1,57 @@
|
||||
application.name=${pom.name}
|
||||
application.version=${pom.version}
|
||||
autoupdate=true
|
||||
max.download.threads=3
|
||||
|
||||
#temp.directory defaults to System.getProperty("java.io.tmpdir")
|
||||
#temp.directory=[path to temp directory]
|
||||
|
||||
# the path to the data directory; the [JAR] signifies to use the relative path
|
||||
# to the dependency-check-core JAR file. This path is only used to construct
|
||||
# the connection string for the H2 driver (or other drivers that require a file path
|
||||
# to be supplied. If you are using another database (MySQL, Oracle, etc.) this property
|
||||
# will not be used. The data.directory will be resolved and if the connection string
|
||||
# below contains a %s then the data.directory will replace the %s.
|
||||
data.directory=[JAR]/data
|
||||
data.connection_string=jdbc:h2:file:%s;FILE_LOCK=SERIALIZED;AUTOCOMMIT=ON;
|
||||
#data.connection_string=jdbc:h2:file:%s;AUTO_SERVER=TRUE;AUTOCOMMIT=ON;
|
||||
#data.connection_string=jdbc:mysql://localhost:3306/dependencycheck
|
||||
|
||||
# user name and password for the database connection. The inherent case is to use H2.
|
||||
# As such, this unsecure username/password exist.
|
||||
data.user=dcuser
|
||||
data.password=DC-Pass1337!
|
||||
# The following are only used if the DB Driver is not JDBC4 compliant and/or the driver
|
||||
# is not in the current classpath. Setting these properties will add the give path(s) to
|
||||
# the class loader and then register the driver with the DriverManager. If the class is
|
||||
# not in the path you must specify both the driver name (aka the fully qualified driver name)
|
||||
# and the driver path. The driver path can be a semi-colon separated list of files/directories
|
||||
# to ensure any and all needed files can be added to the classpath to load the driver.
|
||||
# For non-JDBC4 drivers in the classpath only the driver_name needs to be set.
|
||||
# For MOST situations these properties likely do not need to be set.
|
||||
data.driver_name=org.h2.Driver
|
||||
data.driver_path=
|
||||
|
||||
# the path to the cpe xml file
|
||||
cpe.url=http://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.2.xml.gz
|
||||
# the path to the cpe meta data file.
|
||||
cpe.meta.url=http://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.2.meta
|
||||
|
||||
# the number of days that the modified nvd cve data holds data for. We don't need
|
||||
# to update the other files if we are within this timespan. Per NIST this file
|
||||
# holds 8 days of updates, we are using 7 just to be safe.
|
||||
cve.url.modified.validfordays=7
|
||||
|
||||
# the path to the modified nvd cve xml file.
|
||||
cve.url-1.2.modified=http://nvd.nist.gov/download/nvdcve-modified.xml
|
||||
cve.url-2.0.modified=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
|
||||
cve.startyear=2014
|
||||
cve.url-2.0.base=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
|
||||
cve.url-1.2.base=http://nvd.nist.gov/download/nvdcve-%d.xml
|
||||
|
||||
# the URL for searching Nexus for SHA-1 hashes and whether it's enabled
|
||||
analyzer.nexus.enabled=true
|
||||
analyzer.nexus.url=https://repository.sonatype.org/service/local/
|
||||
# If set to true, the proxy will still ONLY be used if the proxy properties (proxy.url, proxy.port)
|
||||
# are configured
|
||||
analyzer.nexus.proxy=true
|
||||
@@ -0,0 +1 @@
|
||||
proxy.port=80
|
||||
9
pom.xml
9
pom.xml
@@ -1,3 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
This file is part of Dependency-Check.
|
||||
|
||||
@@ -14,13 +15,12 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Copyright (c) 2012 - Jeremy Long
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.2.0</version>
|
||||
<version>1.2.2</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
@@ -29,6 +29,7 @@ Copyright (c) 2012 - Jeremy Long
|
||||
<module>dependency-check-ant</module>
|
||||
<module>dependency-check-maven</module>
|
||||
<module>dependency-check-jenkins</module>
|
||||
<module>dependency-check-utils</module>
|
||||
</modules>
|
||||
<name>Dependency-Check</name>
|
||||
<url>https://github.com/jeremylong/DependencyCheck.git</url>
|
||||
@@ -244,4 +245,4 @@ Copyright (c) 2012 - Jeremy Long
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
</project>
|
||||
16
src/site/markdown/archive-analyzer.md
Normal file
16
src/site/markdown/archive-analyzer.md
Normal file
@@ -0,0 +1,16 @@
|
||||
Archive Analyzer
|
||||
==============
|
||||
|
||||
Dependency-check includes an analyzer an archive analyzer that will attempt
|
||||
to extract files from the archive that are supported by the other file type
|
||||
analyzers.
|
||||
|
||||
Files Types Scanned: ZIP, EAR, WAR, JAR, SAR, APK, NUPKG, TAR, GZ, TGZ
|
||||
|
||||
Additional file extensions for ZIP archives can be added, see the configuration
|
||||
section in the Maven, Ant, or CLI interfaces for more information on configuration.
|
||||
|
||||
Note, since this analyzer does examine the contents of a JAR file there are times
|
||||
that you may see additional entries in the report and/or warnings in the log file (if used)
|
||||
for DLL or EXE files contained within the JAR file. In almost all cases these can
|
||||
be ignored as it is fairly rare to have a .NET dll or exe within a JAR file.
|
||||
10
src/site/markdown/assembly-analyzer.md
Normal file
10
src/site/markdown/assembly-analyzer.md
Normal file
@@ -0,0 +1,10 @@
|
||||
Assembly Analyzer
|
||||
==============
|
||||
|
||||
Dependency-check includes an analyzer that scans .NET dll and exe files and collect as
|
||||
much information it can about the files as it can. The information collected
|
||||
is internally referred to as evidence and is grouped into vendor, product, and version
|
||||
buckets. Other analyzers later use this evidence to identify any Common Platform
|
||||
Enumeration (CPE) identifiers that apply.
|
||||
|
||||
Files Types Scanned: EXE, DLL
|
||||
11
src/site/markdown/jar-analyzer.md
Normal file
11
src/site/markdown/jar-analyzer.md
Normal file
@@ -0,0 +1,11 @@
|
||||
Jar Analyzer
|
||||
==============
|
||||
|
||||
Dependency-check includes an analyzer that scans JAR files and collect as
|
||||
much information it can about the file as it can. The information collected
|
||||
is internally referred to as evidence and is grouped into vendor, product, and version
|
||||
buckets. Other analyzers later use this evidence to identify any Common Platform
|
||||
Enumeration (CPE) identifiers that apply. Additionally, if a POM is present
|
||||
the analyzer will add the Maven group, artifact, and version (GAV).
|
||||
|
||||
Files Types Scanned: JAR, WAR
|
||||
@@ -1,7 +1,7 @@
|
||||
Nexus Analyzer
|
||||
==============
|
||||
|
||||
Dependency Check includes an analyzer which will check for the Maven GAV
|
||||
Dependency-check includes an analyzer that will check for the Maven GAV
|
||||
(Group/Artifact/Version) information for artifacts in the scanned area. By
|
||||
default the information comes from [Maven Central][1], but can be configured to
|
||||
use a local repository if necessary. If the artifact's hash is found in the
|
||||
|
||||
13
src/site/markdown/nuspec-analyzer.md
Normal file
13
src/site/markdown/nuspec-analyzer.md
Normal file
@@ -0,0 +1,13 @@
|
||||
Nuspec Analyzer
|
||||
==============
|
||||
|
||||
Dependency-check includes an analyzer that will scan NuGet's Nuspec file to
|
||||
collect information about the component being used. The evidence collected
|
||||
is used by other analyzers to determine if there are any known vulnerabilities
|
||||
associated with the component.
|
||||
|
||||
Note, the Nuspec Analyzer does not scan dependencies defined. However, if
|
||||
the dependencies have been downloaded and may be included in the scan depending
|
||||
on configuration.
|
||||
|
||||
Files Types Scanned: NUSPEC
|
||||
@@ -64,6 +64,15 @@ HTML version of the report. The other common scenario would be to ignore all CVE
|
||||
]]></notes>
|
||||
<cvssBelow>7</cvssBelow>
|
||||
</suppress>
|
||||
<suppress>
|
||||
<notes><![CDATA[
|
||||
This suppresses false positives identified on spring security.
|
||||
]]></notes>
|
||||
<gav regex="true">org\.springframework\.security:spring.*</gav>
|
||||
<cpe>cpe:/a:vmware:springsource_spring_framework</cpe>
|
||||
<cpe>cpe:/a:springsource:spring_framework</cpe>
|
||||
<cpe>cpe:/a:mod_security:mod_security</cpe>
|
||||
</suppress>
|
||||
</suppressions>
|
||||
```
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
@@ -84,9 +84,23 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
<item name="Sample Report" href="./SampleReport.html">
|
||||
<description>Sample Report</description>
|
||||
</item>
|
||||
</menu>
|
||||
<menu name="File Type Analyzers">
|
||||
<item name="Archive Analyzer" href="./archive-analyzer.html">
|
||||
<description>Archive Analyzer</description>
|
||||
</item>
|
||||
<item name="Jar Analyzer" href="./jar-analyzer.html">
|
||||
<description>Jar Analyzer</description>
|
||||
</item>
|
||||
<item name="Nexus Analyzer" href="./nexus-analyzer.html">
|
||||
<description>Nexus Analyzer</description>
|
||||
</item>
|
||||
<item name="Assembly Analyzer" href="./assembly-analyzer.html">
|
||||
<description>Assembly Analyzer</description>
|
||||
</item>
|
||||
<item name="Nuspec Analyzer" href="./nuspec-analyzer.html">
|
||||
<description>Nuspec Analyzer</description>
|
||||
</item>
|
||||
</menu>
|
||||
<menu name="Modules">
|
||||
<item name="dependency-check-core" href="./dependency-check-core/index.html">
|
||||
|
||||
Reference in New Issue
Block a user