mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-01-15 16:23:37 +01:00
Compare commits
72 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3264becdc2 | ||
|
|
845bf6ada1 | ||
|
|
865ef2beb3 | ||
|
|
ace5353595 | ||
|
|
56a43fe17b | ||
|
|
46f36dc7ab | ||
|
|
db0ac70b71 | ||
|
|
6cfcc903df | ||
|
|
2ccae9f434 | ||
|
|
139bf0ee35 | ||
|
|
1ce6e37e78 | ||
|
|
462026e7e9 | ||
|
|
2f180510b8 | ||
|
|
53e67dfb27 | ||
|
|
ff951130b6 | ||
|
|
69ebb53a05 | ||
|
|
1a2a3d1945 | ||
|
|
c8b967ba37 | ||
|
|
83b713a781 | ||
|
|
c930568df7 | ||
|
|
95e2c6179f | ||
|
|
dfdf690575 | ||
|
|
db30517516 | ||
|
|
534b2e59a0 | ||
|
|
5028216058 | ||
|
|
173947fd7d | ||
|
|
9aa6ad216d | ||
|
|
b2a5963f5a | ||
|
|
c80fdee99b | ||
|
|
270db7829d | ||
|
|
5ff9ec9942 | ||
|
|
2fc554e1d4 | ||
|
|
7a35c1638b | ||
|
|
916243468f | ||
|
|
cb56bbc122 | ||
|
|
d1b2d5cb27 | ||
|
|
884b56a4ef | ||
|
|
eeb8d9cdf5 | ||
|
|
e8d7bbd280 | ||
|
|
277ee4c4b2 | ||
|
|
efa6c8135d | ||
|
|
cbb705c367 | ||
|
|
44326cd8c1 | ||
|
|
4592ab4bf5 | ||
|
|
870849f01a | ||
|
|
a00bcc3df2 | ||
|
|
122dc5baf4 | ||
|
|
a276d2da4f | ||
|
|
6f04d4d43b | ||
|
|
a966f263a2 | ||
|
|
ac5a23ef29 | ||
|
|
b82804018d | ||
|
|
35b0b684df | ||
|
|
a627ca2127 | ||
|
|
05a1096e25 | ||
|
|
9600e56344 | ||
|
|
1bb0871948 | ||
|
|
6ff50689e1 | ||
|
|
9b025ddece | ||
|
|
12fd77f0b2 | ||
|
|
0e60883b3d | ||
|
|
33b6bfe5be | ||
|
|
8167146372 | ||
|
|
21bbedaf04 | ||
|
|
998aedde33 | ||
|
|
25050da2c9 | ||
|
|
a74cf8ec4d | ||
|
|
e06f0a5d49 | ||
|
|
9d1ea4b551 | ||
|
|
e0410783be | ||
|
|
d064337c15 | ||
|
|
4340368e49 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -16,3 +16,5 @@ dependency-reduced-pom.xml
|
|||||||
Gemfile
|
Gemfile
|
||||||
Gemfile.lock
|
Gemfile.lock
|
||||||
_site/**
|
_site/**
|
||||||
|
#unknown as to why these are showing up... but need to be ignored.
|
||||||
|
.LCKpom.xml~
|
||||||
@@ -21,7 +21,7 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-parent</artifactId>
|
<artifactId>dependency-check-parent</artifactId>
|
||||||
<version>1.1.2</version>
|
<version>1.1.4</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>dependency-check-ant</artifactId>
|
<artifactId>dependency-check-ant</artifactId>
|
||||||
|
|||||||
@@ -457,6 +457,81 @@ public class DependencyCheckTask extends Task {
|
|||||||
this.showSummary = showSummary;
|
this.showSummary = showSummary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether or not the analyzer is enabled.
|
||||||
|
*
|
||||||
|
* @param jarAnalyzerEnabled the value of the new setting
|
||||||
|
*/
|
||||||
|
public void setJarAnalyzerEnabled(boolean jarAnalyzerEnabled) {
|
||||||
|
this.jarAnalyzerEnabled = jarAnalyzerEnabled;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Whether or not the Archive Analyzer is enabled.
|
||||||
|
*/
|
||||||
|
private boolean archiveAnalyzerEnabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the analyzer is enabled.
|
||||||
|
*
|
||||||
|
* @return true if the analyzer is enabled
|
||||||
|
*/
|
||||||
|
public boolean isArchiveAnalyzerEnabled() {
|
||||||
|
return archiveAnalyzerEnabled;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Whether or not the .NET Assembly Analyzer is enabled.
|
||||||
|
*/
|
||||||
|
private boolean assemblyAnalyzerEnabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether or not the analyzer is enabled.
|
||||||
|
*
|
||||||
|
* @param archiveAnalyzerEnabled the value of the new setting
|
||||||
|
*/
|
||||||
|
public void setArchiveAnalyzerEnabled(boolean archiveAnalyzerEnabled) {
|
||||||
|
this.archiveAnalyzerEnabled = archiveAnalyzerEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the analyzer is enabled.
|
||||||
|
*
|
||||||
|
* @return true if the analyzer is enabled
|
||||||
|
*/
|
||||||
|
public boolean isAssemblyAnalyzerEnabled() {
|
||||||
|
return assemblyAnalyzerEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether or not the analyzer is enabled.
|
||||||
|
*
|
||||||
|
* @param assemblyAnalyzerEnabled the value of the new setting
|
||||||
|
*/
|
||||||
|
public void setAssemblyAnalyzerEnabled(boolean assemblyAnalyzerEnabled) {
|
||||||
|
this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Whether or not the .NET Nuspec Analyzer is enabled.
|
||||||
|
*/
|
||||||
|
private boolean nuspecAnalyzerEnabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the analyzer is enabled.
|
||||||
|
*
|
||||||
|
* @return true if the analyzer is enabled
|
||||||
|
*/
|
||||||
|
public boolean isNuspecAnalyzerEnabled() {
|
||||||
|
return nuspecAnalyzerEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether or not the analyzer is enabled.
|
||||||
|
*
|
||||||
|
* @param nuspecAnalyzerEnabled the value of the new setting
|
||||||
|
*/
|
||||||
|
public void setNuspecAnalyzerEnabled(boolean nuspecAnalyzerEnabled) {
|
||||||
|
this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not the nexus analyzer is enabled.
|
* Whether or not the nexus analyzer is enabled.
|
||||||
*/
|
*/
|
||||||
@@ -753,6 +828,28 @@ public class DependencyCheckTask extends Task {
|
|||||||
public void setCveUrl20Base(String cveUrl20Base) {
|
public void setCveUrl20Base(String cveUrl20Base) {
|
||||||
this.cveUrl20Base = cveUrl20Base;
|
this.cveUrl20Base = cveUrl20Base;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* The path to Mono for .NET assembly analysis on non-windows systems.
|
||||||
|
*/
|
||||||
|
private String pathToMono;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of pathToMono.
|
||||||
|
*
|
||||||
|
* @return the value of pathToMono
|
||||||
|
*/
|
||||||
|
public String getPathToMono() {
|
||||||
|
return pathToMono;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of pathToMono.
|
||||||
|
*
|
||||||
|
* @param pathToMono new value of pathToMono
|
||||||
|
*/
|
||||||
|
public void setPathToMono(String pathToMono) {
|
||||||
|
this.pathToMono = pathToMono;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws BuildException {
|
public void execute() throws BuildException {
|
||||||
@@ -885,11 +982,29 @@ public class DependencyCheckTask extends Task {
|
|||||||
if (suppressionFile != null && !suppressionFile.isEmpty()) {
|
if (suppressionFile != null && !suppressionFile.isEmpty()) {
|
||||||
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
|
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//File Type Analyzer Settings
|
||||||
|
//JAR ANALYZER
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled);
|
||||||
|
//NUSPEC ANALYZER
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled);
|
||||||
|
//NEXUS ANALYZER
|
||||||
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
|
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
|
||||||
if (nexusUrl != null && !nexusUrl.isEmpty()) {
|
if (nexusUrl != null && !nexusUrl.isEmpty()) {
|
||||||
Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
|
Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
|
||||||
}
|
}
|
||||||
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy);
|
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy);
|
||||||
|
//ARCHIVE ANALYZER
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled);
|
||||||
|
if (zipExtensions != null && !zipExtensions.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
|
||||||
|
}
|
||||||
|
//ASSEMBLY ANALYZER
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled);
|
||||||
|
if (pathToMono != null && !pathToMono.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
|
||||||
|
}
|
||||||
|
|
||||||
if (databaseDriverName != null && !databaseDriverName.isEmpty()) {
|
if (databaseDriverName != null && !databaseDriverName.isEmpty()) {
|
||||||
Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
|
Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
|
||||||
}
|
}
|
||||||
@@ -905,9 +1020,6 @@ public class DependencyCheckTask extends Task {
|
|||||||
if (databasePassword != null && !databasePassword.isEmpty()) {
|
if (databasePassword != null && !databasePassword.isEmpty()) {
|
||||||
Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword);
|
Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword);
|
||||||
}
|
}
|
||||||
if (zipExtensions != null && !zipExtensions.isEmpty()) {
|
|
||||||
Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
|
|
||||||
}
|
|
||||||
if (cveUrl12Modified != null && !cveUrl12Modified.isEmpty()) {
|
if (cveUrl12Modified != null && !cveUrl12Modified.isEmpty()) {
|
||||||
Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
|
Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
|
||||||
}
|
}
|
||||||
@@ -1011,4 +1123,18 @@ public class DependencyCheckTask extends Task {
|
|||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the Jar Analyzer is enabled.
|
||||||
|
*/
|
||||||
|
private boolean jarAnalyzerEnabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the analyzer is enabled.
|
||||||
|
*
|
||||||
|
* @return true if the analyzer is enabled
|
||||||
|
*/
|
||||||
|
public boolean isJarAnalyzerEnabled() {
|
||||||
|
return jarAnalyzerEnabled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,33 +18,60 @@ the project's dependencies.
|
|||||||
</dependency-check>
|
</dependency-check>
|
||||||
</target>
|
</target>
|
||||||
```
|
```
|
||||||
The following table lists the configurable properties:
|
|
||||||
|
|
||||||
Property | Description | Requirement | Default Value
|
Configuration
|
||||||
----------------------|-------------|-------------|------------
|
====================
|
||||||
applicationName | The name of the application to use in the generated report. | Required |
|
The following properties can be set on the dependency-check-maven plugin.
|
||||||
reportFormat | The format of the report to be generated. Allowed values are: HTML, XML, VULN, or ALL. The default value is HTML.| Optional | HTML
|
|
||||||
reportOutputDirectory | The directory where dependency-check will store data used for analysis. Defaults to the current working directory. | Optional |
|
Property | Description | Default Value
|
||||||
failBuildOn | If set and a CVE is found that is greater then the specified value the build will fail. The default value is 11 which means that the build will not fail. Valid values are 0-11. | Optional | 11
|
---------------------|------------------------------------|------------------
|
||||||
autoUpdate | If set to false the NVD CVE data is not automatically updated. Setting this to false could result in false negatives. However, this may be required in some environments. | Optional | true
|
autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. | true
|
||||||
dataDirectory | The directory where dependency-check will store data used for analysis. Defaults to a folder called, called 'dependency-check-data', that is in the same directory as the dependency-check-ant jar file was installed in. *It is not recommended to change this.* | Optional |
|
externalReport | When using as a Site plugin this parameter sets whether or not the external report format should be used. | false
|
||||||
logFile | The file path to write verbose logging information. | Optional |
|
outputDirectory | The location to write the report(s). Note, this is not used if generating the report as part of a `mvn site` build | 'target'
|
||||||
suppressionFile | An XML file conforming to the suppression schema that suppresses findings; this is used to hide [false positives](../suppression.html). | Optional |
|
failBuildOnCVSS | Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which means since the CVSS scores are 0-10, by default the build will never fail. | 11
|
||||||
proxyUrl | Defines the proxy used to connect to the Internet. | Optional |
|
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
|
||||||
proxyPort | Defines the port for the proxy. | Optional |
|
logFile | The file path to write verbose logging information. |
|
||||||
proxyUsername | Defines the proxy user name. | Optional |
|
suppressionFile | The file path to the XML suppression file \- used to suppress [false positives](../suppression.html) |
|
||||||
proxyPassword | Defines the proxy password. | Optional |
|
proxyUrl | The Proxy URL. |
|
||||||
connectionTimeout | The connection timeout used when downloading data files from the Internet. | Optional |
|
proxyPort | The Proxy Port. |
|
||||||
nexusAnalyzerEnabled | The connection timeout used when downloading data files from the Internet. | Optional |
|
proxyUsername | Defines the proxy user name. |
|
||||||
nexusUrl | The connection timeout used when downloading data files from the Internet. | Optional |
|
proxyPassword | Defines the proxy password. |
|
||||||
nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | Optional | true
|
connectionTimeout | The URL Connection Timeout. |
|
||||||
databaseDriverName | The name of the database driver. Example: org.h2.Driver. | Optional |
|
|
||||||
databaseDriverPath | The path to the database driver JAR file; only used if the driver is not in the class path. | Optional |
|
Analyzer Configuration
|
||||||
connectionString | The connection string used to connect to the database. | Optional |
|
====================
|
||||||
databaseUser | The username used when connecting to the database. | Optional | dcuser
|
The following properties are used to configure the various file type analyzers.
|
||||||
databasePassword | The password used when connecting to the database. | Optional |
|
These properties can be used to turn off specific analyzers if it is not needed.
|
||||||
zipExtensions | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. | Optional |
|
Note, that specific analyzers will automatically disable themselves if no file
|
||||||
cveUrl12Modified | URL for the modified CVE 1.2 | Optional | http://nvd.nist.gov/download/nvdcve-modified.xml
|
types that they support are detected - so specifically disabling them may not
|
||||||
cveUrl20Modified | URL for the modified CVE 2.0 | Optional | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
|
be needed.
|
||||||
cveUrl12Base | Base URL for each year's CVE 1.2, the %d will be replaced with the year | Optional | http://nvd.nist.gov/download/nvdcve-%d.xml
|
|
||||||
cveUrl20Base | Base URL for each year's CVE 2.0, the %d will be replaced with the year | Optional | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
|
Property | Description | Default Value
|
||||||
|
------------------------|------------------------------------|------------------
|
||||||
|
archiveAnalyzerEnabled | Sets whether the Archive Analyzer will be used. | true
|
||||||
|
zipExtensions | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |
|
||||||
|
jarAnalyzer | Sets whether Jar Analyzer will be used. | true
|
||||||
|
nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. | true
|
||||||
|
nexusUrl | Defines the Nexus URL. | https://repository.sonatype.org/service/local/
|
||||||
|
nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true
|
||||||
|
nuspecAnalyzerEnabled | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | true
|
||||||
|
assemblyAnalyzerEnabled | Sets whether or not the .NET Assembly Analyzer should be used. | true
|
||||||
|
pathToMono | The path to Mono for .NET assembly analysis on non-windows systems |
|
||||||
|
|
||||||
|
Advanced Configuration
|
||||||
|
====================
|
||||||
|
The following properties can be configured in the plugin. However, they are less frequently changed. One exception
|
||||||
|
may be the cvedUrl properties, which can be used to host a mirror of the NVD within an enterprise environment.
|
||||||
|
|
||||||
|
Property | Description | Default Value
|
||||||
|
---------------------|-------------------------------------------------------------------------|------------------
|
||||||
|
cveUrl12Modified | URL for the modified CVE 1.2 | http://nvd.nist.gov/download/nvdcve-modified.xml
|
||||||
|
cveUrl20Modified | URL for the modified CVE 2.0 | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
|
||||||
|
cveUrl12Base | Base URL for each year's CVE 1.2, the %d will be replaced with the year | http://nvd.nist.gov/download/nvdcve-%d.xml
|
||||||
|
cveUrl20Base | Base URL for each year's CVE 2.0, the %d will be replaced with the year | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
|
||||||
|
dataDirectory | Data directory to hold SQL CVEs contents. This should generally not be changed. |
|
||||||
|
databaseDriverName | The name of the database driver. Example: org.h2.Driver. |
|
||||||
|
databaseDriverPath | The path to the database driver JAR file; only used if the driver is not in the class path. |
|
||||||
|
connectionString | The connection string used to connect to the database. |
|
||||||
|
databaseUser | The username used when connecting to the database. |
|
||||||
|
databasePassword | The password used when connecting to the database. |
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public class DependencyCheckTaskTest extends BuildFileTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAddFileSet() throws Exception {
|
public void testAddFileSet() throws Exception {
|
||||||
File report = new File("target/DependencyCheck-Report.html");
|
File report = new File("target/dependency-check-report.html");
|
||||||
if (report.exists()) {
|
if (report.exists()) {
|
||||||
if (!report.delete()) {
|
if (!report.delete()) {
|
||||||
throw new Exception("Unable to delete 'target/DependencyCheck-Report.html' prior to test.");
|
throw new Exception("Unable to delete 'target/DependencyCheck-Report.html' prior to test.");
|
||||||
@@ -83,7 +83,7 @@ public class DependencyCheckTaskTest extends BuildFileTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAddFileList() throws Exception {
|
public void testAddFileList() throws Exception {
|
||||||
File report = new File("target/DependencyCheck-Report.xml");
|
File report = new File("target/dependency-check-report.xml");
|
||||||
if (report.exists()) {
|
if (report.exists()) {
|
||||||
if (!report.delete()) {
|
if (!report.delete()) {
|
||||||
throw new Exception("Unable to delete 'target/DependencyCheck-Report.xml' prior to test.");
|
throw new Exception("Unable to delete 'target/DependencyCheck-Report.xml' prior to test.");
|
||||||
@@ -101,7 +101,7 @@ public class DependencyCheckTaskTest extends BuildFileTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAddDirSet() throws Exception {
|
public void testAddDirSet() throws Exception {
|
||||||
File report = new File("target/DependencyCheck-Vulnerability.html");
|
File report = new File("target/dependency-check-vulnerability.html");
|
||||||
if (report.exists()) {
|
if (report.exists()) {
|
||||||
if (!report.delete()) {
|
if (!report.delete()) {
|
||||||
throw new Exception("Unable to delete 'target/DependencyCheck-Vulnerability.html' prior to test.");
|
throw new Exception("Unable to delete 'target/DependencyCheck-Vulnerability.html' prior to test.");
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-parent</artifactId>
|
<artifactId>dependency-check-parent</artifactId>
|
||||||
<version>1.1.2</version>
|
<version>1.1.4</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>dependency-check-cli</artifactId>
|
<artifactId>dependency-check-cli</artifactId>
|
||||||
|
|||||||
@@ -158,15 +158,19 @@ public class App {
|
|||||||
final String dataDirectory = cli.getDataDirectory();
|
final String dataDirectory = cli.getDataDirectory();
|
||||||
final File propertiesFile = cli.getPropertiesFile();
|
final File propertiesFile = cli.getPropertiesFile();
|
||||||
final String suppressionFile = cli.getSuppressionFile();
|
final String suppressionFile = cli.getSuppressionFile();
|
||||||
|
final boolean jarDisabled = cli.isJarDisabled();
|
||||||
|
final boolean archiveDisabled = cli.isArchiveDisabled();
|
||||||
|
final boolean assemblyDisabled = cli.isAssemblyDisabled();
|
||||||
|
final boolean nuspecDisabled = cli.isNuspecDisabled();
|
||||||
final boolean nexusDisabled = cli.isNexusDisabled();
|
final boolean nexusDisabled = cli.isNexusDisabled();
|
||||||
final String nexusUrl = cli.getNexusUrl();
|
final String nexusUrl = cli.getNexusUrl();
|
||||||
final boolean nexusUsesProxy = cli.isNexusUsesProxy();
|
|
||||||
final String databaseDriverName = cli.getDatabaseDriverName();
|
final String databaseDriverName = cli.getDatabaseDriverName();
|
||||||
final String databaseDriverPath = cli.getDatabaseDriverPath();
|
final String databaseDriverPath = cli.getDatabaseDriverPath();
|
||||||
final String connectionString = cli.getConnectionString();
|
final String connectionString = cli.getConnectionString();
|
||||||
final String databaseUser = cli.getDatabaseUser();
|
final String databaseUser = cli.getDatabaseUser();
|
||||||
final String databasePassword = cli.getDatabasePassword();
|
final String databasePassword = cli.getDatabasePassword();
|
||||||
final String additionalZipExtensions = cli.getAdditionalZipExtensions();
|
final String additionalZipExtensions = cli.getAdditionalZipExtensions();
|
||||||
|
final String pathToMono = cli.getPathToMono();
|
||||||
|
|
||||||
if (propertiesFile != null) {
|
if (propertiesFile != null) {
|
||||||
try {
|
try {
|
||||||
@@ -181,6 +185,10 @@ public class App {
|
|||||||
Logger.getLogger(App.class.getName()).log(Level.FINE, null, ex);
|
Logger.getLogger(App.class.getName()).log(Level.FINE, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// We have to wait until we've merged the properties before attempting to set whether we use
|
||||||
|
// the proxy for Nexus since it could be disabled in the properties, but not explicitly stated
|
||||||
|
// on the command line
|
||||||
|
final boolean nexusUsesProxy = cli.isNexusUsesProxy();
|
||||||
if (dataDirectory != null) {
|
if (dataDirectory != null) {
|
||||||
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
|
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
|
||||||
} else if (System.getProperty("basedir") != null) {
|
} else if (System.getProperty("basedir") != null) {
|
||||||
@@ -212,6 +220,13 @@ public class App {
|
|||||||
if (suppressionFile != null && !suppressionFile.isEmpty()) {
|
if (suppressionFile != null && !suppressionFile.isEmpty()) {
|
||||||
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
|
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//File Type Analyzer Settings
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !jarDisabled);
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !archiveDisabled);
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !nuspecDisabled);
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !assemblyDisabled);
|
||||||
|
|
||||||
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !nexusDisabled);
|
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !nexusDisabled);
|
||||||
if (nexusUrl != null && !nexusUrl.isEmpty()) {
|
if (nexusUrl != null && !nexusUrl.isEmpty()) {
|
||||||
Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
|
Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
|
||||||
@@ -235,5 +250,8 @@ public class App {
|
|||||||
if (additionalZipExtensions != null && !additionalZipExtensions.isEmpty()) {
|
if (additionalZipExtensions != null && !additionalZipExtensions.isEmpty()) {
|
||||||
Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions);
|
Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions);
|
||||||
}
|
}
|
||||||
|
if (pathToMono != null && !pathToMono.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import org.apache.commons.cli.Options;
|
|||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.apache.commons.cli.PosixParser;
|
import org.apache.commons.cli.PosixParser;
|
||||||
import org.owasp.dependencycheck.reporting.ReportGenerator.Format;
|
import org.owasp.dependencycheck.reporting.ReportGenerator.Format;
|
||||||
|
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,8 +85,11 @@ public final class CliParser {
|
|||||||
*/
|
*/
|
||||||
private void validateArgs() throws FileNotFoundException, ParseException {
|
private void validateArgs() throws FileNotFoundException, ParseException {
|
||||||
if (isRunScan()) {
|
if (isRunScan()) {
|
||||||
validatePathExists(getScanFiles(), "scan");
|
validatePathExists(getScanFiles(), ArgumentName.SCAN);
|
||||||
validatePathExists(getReportDirectory(), "out");
|
validatePathExists(getReportDirectory(), ArgumentName.OUT);
|
||||||
|
if (getPathToMono() != null) {
|
||||||
|
validatePathExists(getPathToMono(), ArgumentName.PATH_TO_MONO);
|
||||||
|
}
|
||||||
if (!line.hasOption(ArgumentName.APP_NAME)) {
|
if (!line.hasOption(ArgumentName.APP_NAME)) {
|
||||||
throw new ParseException("Missing 'app' argument; the scan cannot be run without the an application name.");
|
throw new ParseException("Missing 'app' argument; the scan cannot be run without the an application name.");
|
||||||
}
|
}
|
||||||
@@ -121,16 +125,18 @@ public final class CliParser {
|
|||||||
* FileNotFoundException is thrown.
|
* FileNotFoundException is thrown.
|
||||||
*
|
*
|
||||||
* @param path the paths to validate if they exists
|
* @param path the paths to validate if they exists
|
||||||
* @param optType the option being validated (e.g. scan, out, etc.)
|
* @param argumentName the argument being validated (e.g. scan, out, etc.)
|
||||||
* @throws FileNotFoundException is thrown if the path being validated does not exist.
|
* @throws FileNotFoundException is thrown if the path being validated does not exist.
|
||||||
*/
|
*/
|
||||||
private void validatePathExists(String path, String optType) throws FileNotFoundException {
|
private void validatePathExists(String path, String argumentName) throws FileNotFoundException {
|
||||||
final File f = new File(path);
|
if (!path.contains("*.")) {
|
||||||
if (!f.exists()) {
|
final File f = new File(path);
|
||||||
isValid = false;
|
if (!f.exists()) {
|
||||||
final String msg = String.format("Invalid '%s' argument: '%s'", optType, path);
|
isValid = false;
|
||||||
throw new FileNotFoundException(msg);
|
final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
|
||||||
}
|
throw new FileNotFoundException(msg);
|
||||||
|
}
|
||||||
|
} // else { // TODO add a validation for *.zip extensions rather then relying on the engine to validate it.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -173,7 +179,8 @@ public final class CliParser {
|
|||||||
.create(ArgumentName.APP_NAME_SHORT);
|
.create(ArgumentName.APP_NAME_SHORT);
|
||||||
|
|
||||||
final Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.SCAN)
|
final Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.SCAN)
|
||||||
.withDescription("The path to scan - this option can be specified multiple times.")
|
.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(ArgumentName.SCAN_SHORT);
|
||||||
|
|
||||||
final Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.PROP)
|
final Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.PROP)
|
||||||
@@ -196,24 +203,6 @@ public final class CliParser {
|
|||||||
.withDescription("The file path to the suppression XML file.")
|
.withDescription("The file path to the suppression XML file.")
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
final Option disableNexusAnalyzer = OptionBuilder.withLongOpt(ArgumentName.DISABLE_NEXUS)
|
|
||||||
.withDescription("Disable the Nexus Analyzer.")
|
|
||||||
.create();
|
|
||||||
|
|
||||||
final Option nexusUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ArgumentName.NEXUS_URL)
|
|
||||||
.withDescription("The url to the Nexus Server.")
|
|
||||||
.create();
|
|
||||||
|
|
||||||
final Option nexusUsesProxy = OptionBuilder.withArgName("true/false").hasArg().withLongOpt(ArgumentName.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)
|
|
||||||
.withDescription("A comma seperated list of additional extensions to be scanned as ZIP files "
|
|
||||||
+ "(ZIP, EAR, WAR are already treated as zip files)")
|
|
||||||
.create();
|
|
||||||
|
|
||||||
//This is an option group because it can be specified more then once.
|
//This is an option group because it can be specified more then once.
|
||||||
final OptionGroup og = new OptionGroup();
|
final OptionGroup og = new OptionGroup();
|
||||||
og.addOption(path);
|
og.addOption(path);
|
||||||
@@ -228,11 +217,7 @@ public final class CliParser {
|
|||||||
.addOption(noUpdate)
|
.addOption(noUpdate)
|
||||||
.addOption(props)
|
.addOption(props)
|
||||||
.addOption(verboseLog)
|
.addOption(verboseLog)
|
||||||
.addOption(suppressionFile)
|
.addOption(suppressionFile);
|
||||||
.addOption(disableNexusAnalyzer)
|
|
||||||
.addOption(nexusUrl)
|
|
||||||
.addOption(nexusUsesProxy)
|
|
||||||
.addOption(additionalZipExtensions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -272,19 +257,58 @@ public final class CliParser {
|
|||||||
final Option connectionString = OptionBuilder.withArgName("connStr").hasArg().withLongOpt(ArgumentName.CONNECTION_STRING)
|
final Option connectionString = OptionBuilder.withArgName("connStr").hasArg().withLongOpt(ArgumentName.CONNECTION_STRING)
|
||||||
.withDescription("The connection string to the database.")
|
.withDescription("The connection string to the database.")
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
final Option dbUser = OptionBuilder.withArgName("user").hasArg().withLongOpt(ArgumentName.DB_NAME)
|
final Option dbUser = OptionBuilder.withArgName("user").hasArg().withLongOpt(ArgumentName.DB_NAME)
|
||||||
.withDescription("The username used to connect to the database.")
|
.withDescription("The username used to connect to the database.")
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
final Option dbPassword = OptionBuilder.withArgName("password").hasArg().withLongOpt(ArgumentName.DB_PASSWORD)
|
final Option dbPassword = OptionBuilder.withArgName("password").hasArg().withLongOpt(ArgumentName.DB_PASSWORD)
|
||||||
.withDescription("The password for connecting to the database.")
|
.withDescription("The password for connecting to the database.")
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
final Option dbDriver = OptionBuilder.withArgName("driver").hasArg().withLongOpt(ArgumentName.DB_DRIVER)
|
final Option dbDriver = OptionBuilder.withArgName("driver").hasArg().withLongOpt(ArgumentName.DB_DRIVER)
|
||||||
.withDescription("The database driver name.")
|
.withDescription("The database driver name.")
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
final Option dbDriverPath = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.DB_DRIVER_PATH)
|
final Option dbDriverPath = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.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.")
|
.withDescription("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.")
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
|
final Option disableJarAnalyzer = OptionBuilder.withLongOpt(ArgumentName.DISABLE_JAR)
|
||||||
|
.withDescription("Disable the Jar Analyzer.")
|
||||||
|
.create();
|
||||||
|
final Option disableArchiveAnalyzer = OptionBuilder.withLongOpt(ArgumentName.DISABLE_ARCHIVE)
|
||||||
|
.withDescription("Disable the Archive Analyzer.")
|
||||||
|
.create();
|
||||||
|
final Option disableNuspecAnalyzer = OptionBuilder.withLongOpt(ArgumentName.DISABLE_NUSPEC)
|
||||||
|
.withDescription("Disable the Nuspec Analyzer.")
|
||||||
|
.create();
|
||||||
|
final Option disableAssemblyAnalyzer = OptionBuilder.withLongOpt(ArgumentName.DISABLE_ASSEMBLY)
|
||||||
|
.withDescription("Disable the .NET Assembly Analyzer.")
|
||||||
|
.create();
|
||||||
|
|
||||||
|
final Option disableNexusAnalyzer = OptionBuilder.withLongOpt(ArgumentName.DISABLE_NEXUS)
|
||||||
|
.withDescription("Disable the Nexus Analyzer.")
|
||||||
|
.create();
|
||||||
|
|
||||||
|
final Option nexusUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ArgumentName.NEXUS_URL)
|
||||||
|
.withDescription("The url to the Nexus Server.")
|
||||||
|
.create();
|
||||||
|
|
||||||
|
final Option nexusUsesProxy = OptionBuilder.withArgName("true/false").hasArg().withLongOpt(ArgumentName.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)
|
||||||
|
.withDescription("A comma seperated 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)
|
||||||
|
.withDescription("The path to Mono for .NET Assembly analysis on non-windows systems.")
|
||||||
|
.create();
|
||||||
|
|
||||||
options.addOption(proxyPort)
|
options.addOption(proxyPort)
|
||||||
.addOption(proxyUrl)
|
.addOption(proxyUrl)
|
||||||
.addOption(proxyUsername)
|
.addOption(proxyUsername)
|
||||||
@@ -295,7 +319,16 @@ public final class CliParser {
|
|||||||
.addOption(data)
|
.addOption(data)
|
||||||
.addOption(dbPassword)
|
.addOption(dbPassword)
|
||||||
.addOption(dbDriver)
|
.addOption(dbDriver)
|
||||||
.addOption(dbDriverPath);
|
.addOption(dbDriverPath)
|
||||||
|
.addOption(disableJarAnalyzer)
|
||||||
|
.addOption(disableArchiveAnalyzer)
|
||||||
|
.addOption(disableAssemblyAnalyzer)
|
||||||
|
.addOption(disableNuspecAnalyzer)
|
||||||
|
.addOption(disableNexusAnalyzer)
|
||||||
|
.addOption(nexusUrl)
|
||||||
|
.addOption(nexusUsesProxy)
|
||||||
|
.addOption(additionalZipExtensions)
|
||||||
|
.addOption(pathToMono);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -325,6 +358,42 @@ public final class CliParser {
|
|||||||
return (line != null) && isValid && line.hasOption(ArgumentName.SCAN);
|
return (line != null) && isValid && line.hasOption(ArgumentName.SCAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the disableJar command line argument was specified.
|
||||||
|
*
|
||||||
|
* @return true if the disableJar command line argument was specified; otherwise false
|
||||||
|
*/
|
||||||
|
public boolean isJarDisabled() {
|
||||||
|
return (line != null) && line.hasOption(ArgumentName.DISABLE_JAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the disableArchive command line argument was specified.
|
||||||
|
*
|
||||||
|
* @return true if the disableArchive command line argument was specified; otherwise false
|
||||||
|
*/
|
||||||
|
public boolean isArchiveDisabled() {
|
||||||
|
return (line != null) && line.hasOption(ArgumentName.DISABLE_ARCHIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the disableNuspec command line argument was specified.
|
||||||
|
*
|
||||||
|
* @return true if the disableNuspec command line argument was specified; otherwise false
|
||||||
|
*/
|
||||||
|
public boolean isNuspecDisabled() {
|
||||||
|
return (line != null) && line.hasOption(ArgumentName.DISABLE_NUSPEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the disableAssembly command line argument was specified.
|
||||||
|
*
|
||||||
|
* @return true if the disableAssembly command line argument was specified; otherwise false
|
||||||
|
*/
|
||||||
|
public boolean isAssemblyDisabled() {
|
||||||
|
return (line != null) && line.hasOption(ArgumentName.DISABLE_ASSEMBLY);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the disableNexus command line argument was specified.
|
* Returns true if the disableNexus command line argument was specified.
|
||||||
*
|
*
|
||||||
@@ -354,8 +423,14 @@ public final class CliParser {
|
|||||||
* @return true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false
|
* @return true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false
|
||||||
*/
|
*/
|
||||||
public boolean isNexusUsesProxy() {
|
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(ArgumentName.NEXUS_USES_PROXY)) {
|
||||||
return true;
|
try {
|
||||||
|
return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY);
|
||||||
|
} catch (InvalidSettingException ise) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return Boolean.parseBoolean(line.getOptionValue(ArgumentName.NEXUS_USES_PROXY));
|
return Boolean.parseBoolean(line.getOptionValue(ArgumentName.NEXUS_USES_PROXY));
|
||||||
}
|
}
|
||||||
@@ -403,6 +478,15 @@ public final class CliParser {
|
|||||||
return line.getOptionValue(ArgumentName.OUT, ".");
|
return line.getOptionValue(ArgumentName.OUT, ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the path to Mono for .NET Assembly analysis on non-windows systems.
|
||||||
|
*
|
||||||
|
* @return the path to Mono
|
||||||
|
*/
|
||||||
|
public String getPathToMono() {
|
||||||
|
return line.getOptionValue(ArgumentName.PATH_TO_MONO);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the output format specified on the command line. Defaults to HTML if no format was specified.
|
* Returns the output format specified on the command line. Defaults to HTML if no format was specified.
|
||||||
*
|
*
|
||||||
@@ -683,7 +767,7 @@ public final class CliParser {
|
|||||||
/**
|
/**
|
||||||
* The short CLI argument name for setting the location of an additional properties file.
|
* The short CLI argument name for setting the location of an additional properties file.
|
||||||
*/
|
*/
|
||||||
public static final String PROP_SHORT = "p";
|
public static final String PROP_SHORT = "P";
|
||||||
/**
|
/**
|
||||||
* The CLI argument name for setting the location of an additional properties file.
|
* The CLI argument name for setting the location of an additional properties file.
|
||||||
*/
|
*/
|
||||||
@@ -708,6 +792,22 @@ public final class CliParser {
|
|||||||
* The CLI argument name for setting the location of the suppression file.
|
* The CLI argument name for setting the location of the suppression file.
|
||||||
*/
|
*/
|
||||||
public static final String SUPPRESION_FILE = "suppression";
|
public static final String SUPPRESION_FILE = "suppression";
|
||||||
|
/**
|
||||||
|
* Disables the Jar Analyzer.
|
||||||
|
*/
|
||||||
|
public static final String DISABLE_JAR = "disableJar";
|
||||||
|
/**
|
||||||
|
* Disables the Archive Analyzer.
|
||||||
|
*/
|
||||||
|
public static final String DISABLE_ARCHIVE = "disableArchive";
|
||||||
|
/**
|
||||||
|
* Disables the Assembly Analyzer.
|
||||||
|
*/
|
||||||
|
public static final String DISABLE_ASSEMBLY = "disableAssembly";
|
||||||
|
/**
|
||||||
|
* Disables the Nuspec Analyzer.
|
||||||
|
*/
|
||||||
|
public static final String DISABLE_NUSPEC = "disableNuspec";
|
||||||
/**
|
/**
|
||||||
* Disables the Nexus Analyzer.
|
* Disables the Nexus Analyzer.
|
||||||
*/
|
*/
|
||||||
@@ -740,6 +840,10 @@ public final class CliParser {
|
|||||||
* The CLI argument name for setting the path to the database driver; in case it is not on the class path.
|
* The CLI argument name for setting the path to the database driver; in case it is not on the class path.
|
||||||
*/
|
*/
|
||||||
public static final String DB_DRIVER_PATH = "dbDriverPath";
|
public static final String DB_DRIVER_PATH = "dbDriverPath";
|
||||||
|
/**
|
||||||
|
* The CLI argument name for setting the path to mono for .NET Assembly analysis on non-windows systems.
|
||||||
|
*/
|
||||||
|
public static final String PATH_TO_MONO = "mono";
|
||||||
/**
|
/**
|
||||||
* The CLI argument name for setting extra extensions.
|
* The CLI argument name for setting extra extensions.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,32 +1,43 @@
|
|||||||
Command Line Arguments
|
Command Line Arguments
|
||||||
====================
|
======================
|
||||||
|
|
||||||
The following table lists the 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
|
\-a | \-\-app | \<name\> | The name of the application being scanned. This is a required argument. | Required
|
||||||
\-c | \-\-connectiontimeout | \<timeout\> | The connection timeout (in milliseconds) to use when downloading resources. | Optional
|
\-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
|
||||||
\-d | \-\-data | \<path\> | The location of the data directory used to store persistent data. This option should generally not be set. | Optional
|
\-o | \-\-out | \<folder\> | The folder to write reports to. This defaults to the current directory. | Optional
|
||||||
\-f | \-\-format | \<format\> | The output format to write to (XML, HTML, VULN, ALL). The default is HTML. | Required
|
\-f | \-\-format | \<format\> | The output format to write to (XML, HTML, VULN, ALL). The default is HTML. | Required
|
||||||
\-h | \-\-help | | Print the help message. | Optional
|
|
||||||
\-l | \-\-log | \<file\> | The file path to write verbose logging information. | Optional
|
\-l | \-\-log | \<file\> | The file path to write verbose logging information. | Optional
|
||||||
\-n | \-\-noupdate | | Disables the automatic updating of the CPE data. | Optional
|
\-n | \-\-noupdate | | Disables the automatic updating of the CPE data. | Optional
|
||||||
\-o | \-\-out | \<folder\> | The folder to write reports to. This defaults to the current directory. | Optional
|
|
||||||
\-p | \-\-proxyport | \<port\> | The proxy port to use when downloading resources. | Optional
|
|
||||||
| \-\-proxypass | \<pass\> | The proxy password to use when downloading resources. | Optional
|
|
||||||
| \-\-proxyuser | \<user\> | The proxy username to use when downloading resources. | Optional
|
|
||||||
\-s | \-\-scan | \<path\> | The path to scan \- this option can be specified multiple times. | Required
|
|
||||||
| \-\-suppression | \<file\> | The file path to the suppression XML file; used to suppress [false positives](../suppression.html). | Optional
|
| \-\-suppression | \<file\> | The file path to the suppression XML file; used to suppress [false positives](../suppression.html). | Optional
|
||||||
\-u | \-\-proxyurl | \<url\> | The proxy url to use when downloading resources. | Optional
|
\-h | \-\-help | | Print the help message. | Optional
|
||||||
\-v | \-\-version | | Print the version information. | Optional
|
|
||||||
| \-\-advancedHelp | | Print the advanced help message. | Optional
|
| \-\-advancedHelp | | Print the advanced help message. | Optional
|
||||||
| \-\-connectionString | \<connStr\> | The connection string to the database. | Optional
|
\-v | \-\-version | | Print the version information. | Optional
|
||||||
| \-\-dbDriverName | \<driver\> | The database driver name. | Optional
|
|
||||||
| \-\-dbDriverPath | \<path\> | The path to the database driver; note, this does not need to be set unless the JAR is outside of the class path. | Optional
|
Advanced Options
|
||||||
| \-\-dbPassword | \<password\> | The password for connecting to the database. | Optional
|
================
|
||||||
| \-\-dbUser | \<user\> | The username used to connect to the database. | Optional
|
Short | Argument Name | Parameter | Description | Default Value
|
||||||
| \-\-disableNexus | | Disable the Nexus Analyzer. | Optional
|
-------|-----------------------|-----------------|-------------|---------------
|
||||||
| \-\-nexus | \<url\> | The url to the Nexus Server. | Optional
|
| \-\-disableArchive | | Sets whether the Archive Analyzer will be used. | false
|
||||||
| \-\-nexusUsesProxy | \<true\|false\> | Whether or not the defined proxy should be used when connecting to Nexus. | Optional
|
| \-\-zipExtensions | \<strings\> | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |
|
||||||
| \-\-zipExtensions | \<strings\> | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. | Optional
|
| \-\-disableJar | | Sets whether Jar Analyzer will be used. | false
|
||||||
|
| \-\-disableNexus | | Sets whether Nexus Analyzer will be used. | false
|
||||||
|
| \-\-disableNexus | | Disable the Nexus Analyzer. |
|
||||||
|
| \-\-nexus | \<url\> | The url to the Nexus Server. | https://repository.sonatype.org/service/local/
|
||||||
|
| \-\-nexusUsesProxy | \<true\|false\> | Whether or not the defined proxy should be used when connecting to Nexus. | true
|
||||||
|
| \-\-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. |
|
||||||
|
| \-\-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. |
|
||||||
|
| \-\-proxyuser | \<user\> | The proxy username to use when downloading resources. |
|
||||||
|
| \-\-connectionString | \<connStr\> | The connection string to the database. |
|
||||||
|
| \-\-dbDriverName | \<driver\> | The database driver name. |
|
||||||
|
| \-\-dbDriverPath | \<path\> | The path to the database driver; note, this does not need to be set unless the JAR is outside of the class path. |
|
||||||
|
| \-\-dbPassword | \<password\> | The password for connecting to the database. |
|
||||||
|
| \-\-dbUser | \<user\> | The username used to connect to the database. |
|
||||||
|
\-d | \-\-data | \<path\> | The location of the data directory used to store persistent data. This option should generally not be set. |
|
||||||
|
|||||||
@@ -8,20 +8,18 @@ script executable:
|
|||||||
$ chmod +777 dependency-check.sh
|
$ chmod +777 dependency-check.sh
|
||||||
|
|
||||||
To scan a folder on the system you can run:
|
To scan a folder on the system you can run:
|
||||||
|
#set( $H = '#' )
|
||||||
|
|
||||||
Windows
|
$H$H$H Windows
|
||||||
-------
|
|
||||||
dependency-check.bat --app "My App Name" --scan "c:\java\application\lib"
|
dependency-check.bat --app "My App Name" --scan "c:\java\application\lib"
|
||||||
|
|
||||||
\*nix
|
$H$H$H *nix
|
||||||
-------
|
|
||||||
dependency-check.sh --app "My App Name" --scan "/java/application/lib"
|
dependency-check.sh --app "My App Name" --scan "/java/application/lib"
|
||||||
|
|
||||||
To view the command line arguments, see the <a href="arguments.html">arguments page</a>, or you can run:
|
To view the command line arguments, see the <a href="arguments.html">arguments page</a>, or you can run:
|
||||||
Windows
|
|
||||||
-------
|
$H$H$H Windows
|
||||||
dependency-check.bat --help
|
dependency-check.bat --help
|
||||||
|
|
||||||
\*nix
|
$H$H$H *nix
|
||||||
-------
|
|
||||||
dependency-check.sh --help
|
dependency-check.sh --help
|
||||||
@@ -21,7 +21,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-parent</artifactId>
|
<artifactId>dependency-check-parent</artifactId>
|
||||||
<version>1.1.2</version>
|
<version>1.1.4</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>dependency-check-core</artifactId>
|
<artifactId>dependency-check-core</artifactId>
|
||||||
@@ -581,6 +581,13 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.openjpa</groupId>
|
||||||
|
<artifactId>openjpa</artifactId>
|
||||||
|
<version>2.0.1</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<profiles>
|
<profiles>
|
||||||
<profile>
|
<profile>
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import java.util.logging.Logger;
|
|||||||
import org.owasp.dependencycheck.analyzer.AnalysisPhase;
|
import org.owasp.dependencycheck.analyzer.AnalysisPhase;
|
||||||
import org.owasp.dependencycheck.analyzer.Analyzer;
|
import org.owasp.dependencycheck.analyzer.Analyzer;
|
||||||
import org.owasp.dependencycheck.analyzer.AnalyzerService;
|
import org.owasp.dependencycheck.analyzer.AnalyzerService;
|
||||||
|
import org.owasp.dependencycheck.analyzer.FileTypeAnalyzer;
|
||||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
import org.owasp.dependencycheck.data.cpe.CpeMemoryIndex;
|
import org.owasp.dependencycheck.data.cpe.CpeMemoryIndex;
|
||||||
import org.owasp.dependencycheck.data.cpe.IndexException;
|
import org.owasp.dependencycheck.data.cpe.IndexException;
|
||||||
@@ -56,15 +57,15 @@ public class Engine {
|
|||||||
/**
|
/**
|
||||||
* The list of dependencies.
|
* The list of dependencies.
|
||||||
*/
|
*/
|
||||||
private final List<Dependency> dependencies;
|
private List<Dependency> dependencies;
|
||||||
/**
|
/**
|
||||||
* A Map of analyzers grouped by Analysis phase.
|
* A Map of analyzers grouped by Analysis phase.
|
||||||
*/
|
*/
|
||||||
private final EnumMap<AnalysisPhase, List<Analyzer>> analyzers;
|
private final EnumMap<AnalysisPhase, List<Analyzer>> analyzers;
|
||||||
/**
|
/**
|
||||||
* A set of extensions supported by the analyzers.
|
* A Map of analyzers grouped by Analysis phase.
|
||||||
*/
|
*/
|
||||||
private final Set<String> extensions;
|
private final Set<FileTypeAnalyzer> fileTypeAnalyzers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Engine.
|
* Creates a new Engine.
|
||||||
@@ -72,9 +73,10 @@ public class Engine {
|
|||||||
* @throws DatabaseException thrown if there is an error connecting to the database
|
* @throws DatabaseException thrown if there is an error connecting to the database
|
||||||
*/
|
*/
|
||||||
public Engine() throws DatabaseException {
|
public Engine() throws DatabaseException {
|
||||||
this.extensions = new HashSet<String>();
|
|
||||||
this.dependencies = new ArrayList<Dependency>();
|
this.dependencies = new ArrayList<Dependency>();
|
||||||
this.analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class);
|
this.analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class);
|
||||||
|
this.fileTypeAnalyzers = new HashSet<FileTypeAnalyzer>();
|
||||||
|
|
||||||
ConnectionFactory.initialize();
|
ConnectionFactory.initialize();
|
||||||
|
|
||||||
boolean autoUpdate = true;
|
boolean autoUpdate = true;
|
||||||
@@ -110,8 +112,8 @@ public class Engine {
|
|||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
final Analyzer a = iterator.next();
|
final Analyzer a = iterator.next();
|
||||||
analyzers.get(a.getAnalysisPhase()).add(a);
|
analyzers.get(a.getAnalysisPhase()).add(a);
|
||||||
if (a.getSupportedExtensions() != null) {
|
if (a instanceof FileTypeAnalyzer) {
|
||||||
extensions.addAll(a.getSupportedExtensions());
|
this.fileTypeAnalyzers.add((FileTypeAnalyzer) a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,6 +137,13 @@ public class Engine {
|
|||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDependencies(List<Dependency> dependencies) {
|
||||||
|
this.dependencies = dependencies;
|
||||||
|
//for (Dependency dependency: dependencies) {
|
||||||
|
// dependencies.add(dependency);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any
|
* Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any
|
||||||
* dependencies identified are added to the dependency collection.
|
* dependencies identified are added to the dependency collection.
|
||||||
@@ -157,8 +166,21 @@ public class Engine {
|
|||||||
* @param path the path to a file or directory to be analyzed.
|
* @param path the path to a file or directory to be analyzed.
|
||||||
*/
|
*/
|
||||||
public void scan(String path) {
|
public void scan(String path) {
|
||||||
final File file = new File(path);
|
if (path.matches("^.*[\\/]\\*\\.[^\\/:*|?<>\"]+$")) {
|
||||||
scan(file);
|
final String[] parts = path.split("\\*\\.");
|
||||||
|
final String[] ext = new String[]{parts[parts.length - 1]};
|
||||||
|
final File dir = new File(path.substring(0, path.length() - ext[0].length() - 2));
|
||||||
|
if (dir.isDirectory()) {
|
||||||
|
final List<File> files = (List<File>) org.apache.commons.io.FileUtils.listFiles(dir, ext, true);
|
||||||
|
scan(files);
|
||||||
|
} else {
|
||||||
|
final String msg = String.format("Invalid file path provided to scan '%s'", path);
|
||||||
|
Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final File file = new File(path);
|
||||||
|
scan(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -253,7 +275,7 @@ public class Engine {
|
|||||||
final String fileName = file.getName();
|
final String fileName = file.getName();
|
||||||
final String extension = FileUtils.getFileExtension(fileName);
|
final String extension = FileUtils.getFileExtension(fileName);
|
||||||
if (extension != null) {
|
if (extension != null) {
|
||||||
if (extensions.contains(extension)) {
|
if (supportsExtension(extension)) {
|
||||||
final Dependency dependency = new Dependency(file);
|
final Dependency dependency = new Dependency(file);
|
||||||
dependencies.add(dependency);
|
dependencies.add(dependency);
|
||||||
}
|
}
|
||||||
@@ -291,32 +313,13 @@ public class Engine {
|
|||||||
Logger.getLogger(Engine.class.getName()).log(Level.FINE, logHeader);
|
Logger.getLogger(Engine.class.getName()).log(Level.FINE, logHeader);
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.INFO, "Analysis Starting");
|
Logger.getLogger(Engine.class.getName()).log(Level.INFO, "Analysis Starting");
|
||||||
|
|
||||||
//phase one initialize
|
|
||||||
for (AnalysisPhase phase : AnalysisPhase.values()) {
|
|
||||||
final List<Analyzer> analyzerList = analyzers.get(phase);
|
|
||||||
for (Analyzer a : analyzerList) {
|
|
||||||
try {
|
|
||||||
final String msg = String.format("Initializing %s", a.getName());
|
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.FINE, msg);
|
|
||||||
a.initialize();
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
final String msg = String.format("Exception occurred initializing %s.", a.getName());
|
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, msg);
|
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.FINE, null, ex);
|
|
||||||
try {
|
|
||||||
a.close();
|
|
||||||
} catch (Throwable ex1) {
|
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.FINEST, null, ex1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// analysis phases
|
// analysis phases
|
||||||
for (AnalysisPhase phase : AnalysisPhase.values()) {
|
for (AnalysisPhase phase : AnalysisPhase.values()) {
|
||||||
final List<Analyzer> analyzerList = analyzers.get(phase);
|
final List<Analyzer> analyzerList = analyzers.get(phase);
|
||||||
|
|
||||||
for (Analyzer a : analyzerList) {
|
for (Analyzer a : analyzerList) {
|
||||||
|
initializeAnalyzer(a);
|
||||||
|
|
||||||
/* need to create a copy of the collection because some of the
|
/* need to create a copy of the collection because some of the
|
||||||
* analyzers may modify it. This prevents ConcurrentModificationExceptions.
|
* analyzers may modify it. This prevents ConcurrentModificationExceptions.
|
||||||
* This is okay for adds/deletes because it happens per analyzer.
|
* This is okay for adds/deletes because it happens per analyzer.
|
||||||
@@ -326,7 +329,12 @@ public class Engine {
|
|||||||
final Set<Dependency> dependencySet = new HashSet<Dependency>();
|
final Set<Dependency> dependencySet = new HashSet<Dependency>();
|
||||||
dependencySet.addAll(dependencies);
|
dependencySet.addAll(dependencies);
|
||||||
for (Dependency d : dependencySet) {
|
for (Dependency d : dependencySet) {
|
||||||
if (a.supportsExtension(d.getFileExtension())) {
|
boolean shouldAnalyze = true;
|
||||||
|
if (a instanceof FileTypeAnalyzer) {
|
||||||
|
final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a;
|
||||||
|
shouldAnalyze = fAnalyzer.supportsExtension(d.getFileExtension());
|
||||||
|
}
|
||||||
|
if (shouldAnalyze) {
|
||||||
final String msgFile = String.format("Begin Analysis of '%s'", d.getActualFilePath());
|
final String msgFile = String.format("Begin Analysis of '%s'", d.getActualFilePath());
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.FINE, msgFile);
|
Logger.getLogger(Engine.class.getName()).log(Level.FINE, msgFile);
|
||||||
try {
|
try {
|
||||||
@@ -345,18 +353,11 @@ public class Engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//close/cleanup
|
|
||||||
for (AnalysisPhase phase : AnalysisPhase.values()) {
|
for (AnalysisPhase phase : AnalysisPhase.values()) {
|
||||||
final List<Analyzer> analyzerList = analyzers.get(phase);
|
final List<Analyzer> analyzerList = analyzers.get(phase);
|
||||||
|
|
||||||
for (Analyzer a : analyzerList) {
|
for (Analyzer a : analyzerList) {
|
||||||
final String msg = String.format("Closing Analyzer '%s'", a.getName());
|
closeAnalyzer(a);
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.FINE, msg);
|
|
||||||
try {
|
|
||||||
a.close();
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
Logger.getLogger(Engine.class.getName()).log(Level.FINEST, null, ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,6 +369,43 @@ public class Engine {
|
|||||||
Logger.getLogger(Engine.class.getName()).log(Level.INFO, "Analysis Complete");
|
Logger.getLogger(Engine.class.getName()).log(Level.INFO, "Analysis Complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the given analyzer.
|
||||||
|
*
|
||||||
|
* @param analyzer the analyzer to initialize
|
||||||
|
*/
|
||||||
|
private void initializeAnalyzer(Analyzer analyzer) {
|
||||||
|
try {
|
||||||
|
final String msg = String.format("Initializing %s", analyzer.getName());
|
||||||
|
Logger.getLogger(Engine.class.getName()).log(Level.FINE, msg);
|
||||||
|
analyzer.initialize();
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
final String msg = String.format("Exception occurred initializing %s.", analyzer.getName());
|
||||||
|
Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, msg);
|
||||||
|
Logger.getLogger(Engine.class.getName()).log(Level.FINE, null, ex);
|
||||||
|
try {
|
||||||
|
analyzer.close();
|
||||||
|
} catch (Throwable ex1) {
|
||||||
|
Logger.getLogger(Engine.class.getName()).log(Level.FINEST, null, ex1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the given analyzer.
|
||||||
|
*
|
||||||
|
* @param analyzer the analyzer to close
|
||||||
|
*/
|
||||||
|
private void closeAnalyzer(Analyzer analyzer) {
|
||||||
|
final String msg = String.format("Closing Analyzer '%s'", analyzer.getName());
|
||||||
|
Logger.getLogger(Engine.class.getName()).log(Level.FINE, msg);
|
||||||
|
try {
|
||||||
|
analyzer.close();
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
Logger.getLogger(Engine.class.getName()).log(Level.FINEST, null, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cycles through the cached web data sources and calls update on all of them.
|
* Cycles through the cached web data sources and calls update on all of them.
|
||||||
*/
|
*/
|
||||||
@@ -411,15 +449,13 @@ public class Engine {
|
|||||||
if (ext == null) {
|
if (ext == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (AnalysisPhase phase : AnalysisPhase.values()) {
|
boolean scan = false;
|
||||||
final List<Analyzer> analyzerList = analyzers.get(phase);
|
for (FileTypeAnalyzer a : this.fileTypeAnalyzers) {
|
||||||
for (Analyzer a : analyzerList) {
|
/* note, we can't break early on this loop as the analyzers need to know if
|
||||||
if (a.getSupportedExtensions() != null && a.supportsExtension(ext)) {
|
they have files to work on prior to initialization */
|
||||||
return true;
|
scan |= a.supportsExtension(ext);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return scan;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -447,4 +483,5 @@ public class Engine {
|
|||||||
throw new NoDataException("No documents exist");
|
throw new NoDataException("No documents exist");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,973 @@
|
|||||||
|
/*
|
||||||
|
* 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) 2014 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.agent;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
||||||
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||||
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.dependency.Identifier;
|
||||||
|
import org.owasp.dependencycheck.dependency.Vulnerability;
|
||||||
|
import org.owasp.dependencycheck.exception.ScanAgentException;
|
||||||
|
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class provides a way to easily conduct a scan solely based on existing evidence metadata rather than collecting
|
||||||
|
* evidence from the files themselves. This class is based on the Ant task and Maven plugin with the exception that it
|
||||||
|
* takes a list of dependencies that can be programmatically added from data in a spreadsheet, database or some other
|
||||||
|
* datasource and conduct a scan based on this pre-defined evidence.
|
||||||
|
*
|
||||||
|
* <h2>Example:</h2>
|
||||||
|
* <pre>
|
||||||
|
* List<Dependency> dependencies = new ArrayList<Dependency>();
|
||||||
|
* Dependency dependency = new Dependency(new File(FileUtils.getBitBucket()));
|
||||||
|
* dependency.getProductEvidence().addEvidence("my-datasource", "name", "Jetty", Confidence.HIGH);
|
||||||
|
* dependency.getVersionEvidence().addEvidence("my-datasource", "version", "5.1.10", Confidence.HIGH);
|
||||||
|
* dependency.getVendorEvidence().addEvidence("my-datasource", "vendor", "mortbay", Confidence.HIGH);
|
||||||
|
* dependencies.add(dependency);
|
||||||
|
*
|
||||||
|
* DependencyCheckScanAgent scan = new DependencyCheckScanAgent();
|
||||||
|
* scan.setDependencies(dependencies);
|
||||||
|
* scan.setReportFormat(ReportGenerator.Format.ALL);
|
||||||
|
* scan.setReportOutputDirectory(System.getProperty("user.home"));
|
||||||
|
* scan.execute();
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author Steve Springett <steve.springett@owasp.org>
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class DependencyCheckScanAgent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* System specific new line character.
|
||||||
|
*/
|
||||||
|
private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The application name for the report.
|
||||||
|
*/
|
||||||
|
private String applicationName = "Dependency-Check";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of applicationName.
|
||||||
|
*
|
||||||
|
* @return the value of applicationName
|
||||||
|
*/
|
||||||
|
public String getApplicationName() {
|
||||||
|
return applicationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of applicationName.
|
||||||
|
*
|
||||||
|
* @param applicationName new value of applicationName
|
||||||
|
*/
|
||||||
|
public void setApplicationName(String applicationName) {
|
||||||
|
this.applicationName = applicationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The pre-determined dependencies to scan
|
||||||
|
*/
|
||||||
|
private List<Dependency> dependencies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of pre-determined dependencies.
|
||||||
|
*
|
||||||
|
* @return returns a list of dependencies
|
||||||
|
*/
|
||||||
|
public List<Dependency> getDependencies() {
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the list of dependencies to scan.
|
||||||
|
*
|
||||||
|
* @param dependencies new value of dependencies
|
||||||
|
*/
|
||||||
|
public void setDependencies(List<Dependency> dependencies) {
|
||||||
|
this.dependencies = dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The location of the data directory that contains
|
||||||
|
*/
|
||||||
|
private String dataDirectory = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of dataDirectory.
|
||||||
|
*
|
||||||
|
* @return the value of dataDirectory
|
||||||
|
*/
|
||||||
|
public String getDataDirectory() {
|
||||||
|
return dataDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of dataDirectory.
|
||||||
|
*
|
||||||
|
* @param dataDirectory new value of dataDirectory
|
||||||
|
*/
|
||||||
|
public void setDataDirectory(String dataDirectory) {
|
||||||
|
this.dataDirectory = dataDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the destination directory for the generated Dependency-Check report.
|
||||||
|
*/
|
||||||
|
private String reportOutputDirectory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of reportOutputDirectory.
|
||||||
|
*
|
||||||
|
* @return the value of reportOutputDirectory
|
||||||
|
*/
|
||||||
|
public String getReportOutputDirectory() {
|
||||||
|
return reportOutputDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of reportOutputDirectory.
|
||||||
|
*
|
||||||
|
* @param reportOutputDirectory new value of reportOutputDirectory
|
||||||
|
*/
|
||||||
|
public void setReportOutputDirectory(String reportOutputDirectory) {
|
||||||
|
this.reportOutputDirectory = reportOutputDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11
|
||||||
|
* which means since the CVSS scores are 0-10, by default the build will never fail and the CVSS score is set to 11.
|
||||||
|
* The valid range for the fail build on CVSS is 0 to 11, where anything above 10 will not cause the build to fail.
|
||||||
|
*/
|
||||||
|
private float failBuildOnCVSS = 11;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of failBuildOnCVSS.
|
||||||
|
*
|
||||||
|
* @return the value of failBuildOnCVSS
|
||||||
|
*/
|
||||||
|
public float getFailBuildOnCVSS() {
|
||||||
|
return failBuildOnCVSS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of failBuildOnCVSS.
|
||||||
|
*
|
||||||
|
* @param failBuildOnCVSS new value of failBuildOnCVSS
|
||||||
|
*/
|
||||||
|
public void setFailBuildOnCVSS(float failBuildOnCVSS) {
|
||||||
|
this.failBuildOnCVSS = failBuildOnCVSS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to
|
||||||
|
* false. Default is true.
|
||||||
|
*/
|
||||||
|
private boolean autoUpdate = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of autoUpdate.
|
||||||
|
*
|
||||||
|
* @return the value of autoUpdate
|
||||||
|
*/
|
||||||
|
public boolean isAutoUpdate() {
|
||||||
|
return autoUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of autoUpdate.
|
||||||
|
*
|
||||||
|
* @param autoUpdate new value of autoUpdate
|
||||||
|
*/
|
||||||
|
public void setAutoUpdate(boolean autoUpdate) {
|
||||||
|
this.autoUpdate = autoUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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. Default is HTML.
|
||||||
|
*/
|
||||||
|
private ReportGenerator.Format reportFormat = ReportGenerator.Format.HTML;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of reportFormat.
|
||||||
|
*
|
||||||
|
* @return the value of reportFormat
|
||||||
|
*/
|
||||||
|
public ReportGenerator.Format getReportFormat() {
|
||||||
|
return reportFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of reportFormat.
|
||||||
|
*
|
||||||
|
* @param reportFormat new value of reportFormat
|
||||||
|
*/
|
||||||
|
public void setReportFormat(ReportGenerator.Format reportFormat) {
|
||||||
|
this.reportFormat = reportFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Proxy URL.
|
||||||
|
*/
|
||||||
|
private String proxyUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of proxyUrl.
|
||||||
|
*
|
||||||
|
* @return the value of proxyUrl
|
||||||
|
*/
|
||||||
|
public String getProxyUrl() {
|
||||||
|
return proxyUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of proxyUrl.
|
||||||
|
*
|
||||||
|
* @param proxyUrl new value of proxyUrl
|
||||||
|
*/
|
||||||
|
public void setProxyUrl(String proxyUrl) {
|
||||||
|
this.proxyUrl = proxyUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Proxy Port.
|
||||||
|
*/
|
||||||
|
private String proxyPort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of proxyPort.
|
||||||
|
*
|
||||||
|
* @return the value of proxyPort
|
||||||
|
*/
|
||||||
|
public String getProxyPort() {
|
||||||
|
return proxyPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of proxyPort.
|
||||||
|
*
|
||||||
|
* @param proxyPort new value of proxyPort
|
||||||
|
*/
|
||||||
|
public void setProxyPort(String proxyPort) {
|
||||||
|
this.proxyPort = proxyPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Proxy username.
|
||||||
|
*/
|
||||||
|
private String proxyUsername;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of proxyUsername.
|
||||||
|
*
|
||||||
|
* @return the value of proxyUsername
|
||||||
|
*/
|
||||||
|
public String getProxyUsername() {
|
||||||
|
return proxyUsername;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of proxyUsername.
|
||||||
|
*
|
||||||
|
* @param proxyUsername new value of proxyUsername
|
||||||
|
*/
|
||||||
|
public void setProxyUsername(String proxyUsername) {
|
||||||
|
this.proxyUsername = proxyUsername;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Proxy password.
|
||||||
|
*/
|
||||||
|
private String proxyPassword;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of proxyPassword.
|
||||||
|
*
|
||||||
|
* @return the value of proxyPassword
|
||||||
|
*/
|
||||||
|
public String getProxyPassword() {
|
||||||
|
return proxyPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of proxyPassword.
|
||||||
|
*
|
||||||
|
* @param proxyPassword new value of proxyPassword
|
||||||
|
*/
|
||||||
|
public void setProxyPassword(String proxyPassword) {
|
||||||
|
this.proxyPassword = proxyPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Connection Timeout.
|
||||||
|
*/
|
||||||
|
private String connectionTimeout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of connectionTimeout.
|
||||||
|
*
|
||||||
|
* @return the value of connectionTimeout
|
||||||
|
*/
|
||||||
|
public String getConnectionTimeout() {
|
||||||
|
return connectionTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of connectionTimeout.
|
||||||
|
*
|
||||||
|
* @param connectionTimeout new value of connectionTimeout
|
||||||
|
*/
|
||||||
|
public void setConnectionTimeout(String connectionTimeout) {
|
||||||
|
this.connectionTimeout = connectionTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file path used for verbose logging.
|
||||||
|
*/
|
||||||
|
private String logFile = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of logFile.
|
||||||
|
*
|
||||||
|
* @return the value of logFile
|
||||||
|
*/
|
||||||
|
public String getLogFile() {
|
||||||
|
return logFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of logFile.
|
||||||
|
*
|
||||||
|
* @param logFile new value of logFile
|
||||||
|
*/
|
||||||
|
public void setLogFile(String logFile) {
|
||||||
|
this.logFile = logFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path to the suppression file.
|
||||||
|
*/
|
||||||
|
private String suppressionFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of suppressionFile.
|
||||||
|
*
|
||||||
|
* @return the value of suppressionFile
|
||||||
|
*/
|
||||||
|
public String getSuppressionFile() {
|
||||||
|
return suppressionFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of suppressionFile.
|
||||||
|
*
|
||||||
|
* @param suppressionFile new value of suppressionFile
|
||||||
|
*/
|
||||||
|
public void setSuppressionFile(String suppressionFile) {
|
||||||
|
this.suppressionFile = suppressionFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* flag indicating whether or not to show a summary of findings.
|
||||||
|
*/
|
||||||
|
private boolean showSummary = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of showSummary.
|
||||||
|
*
|
||||||
|
* @return the value of showSummary
|
||||||
|
*/
|
||||||
|
public boolean isShowSummary() {
|
||||||
|
return showSummary;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of showSummary.
|
||||||
|
*
|
||||||
|
* @param showSummary new value of showSummary
|
||||||
|
*/
|
||||||
|
public void setShowSummary(boolean showSummary) {
|
||||||
|
this.showSummary = showSummary;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the nexus analyzer is enabled.
|
||||||
|
*/
|
||||||
|
private boolean nexusAnalyzerEnabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of nexusAnalyzerEnabled.
|
||||||
|
*
|
||||||
|
* @return the value of nexusAnalyzerEnabled
|
||||||
|
*/
|
||||||
|
public boolean isNexusAnalyzerEnabled() {
|
||||||
|
return nexusAnalyzerEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of nexusAnalyzerEnabled.
|
||||||
|
*
|
||||||
|
* @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled
|
||||||
|
*/
|
||||||
|
public void setNexusAnalyzerEnabled(boolean nexusAnalyzerEnabled) {
|
||||||
|
this.nexusAnalyzerEnabled = nexusAnalyzerEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL of the Nexus server.
|
||||||
|
*/
|
||||||
|
private String nexusUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of nexusUrl.
|
||||||
|
*
|
||||||
|
* @return the value of nexusUrl
|
||||||
|
*/
|
||||||
|
public String getNexusUrl() {
|
||||||
|
return nexusUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of nexusUrl.
|
||||||
|
*
|
||||||
|
* @param nexusUrl new value of nexusUrl
|
||||||
|
*/
|
||||||
|
public void setNexusUrl(String nexusUrl) {
|
||||||
|
this.nexusUrl = nexusUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the defined proxy should be used when connecting to Nexus.
|
||||||
|
*/
|
||||||
|
private boolean nexusUsesProxy = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of nexusUsesProxy.
|
||||||
|
*
|
||||||
|
* @return the value of nexusUsesProxy
|
||||||
|
*/
|
||||||
|
public boolean isNexusUsesProxy() {
|
||||||
|
return nexusUsesProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of nexusUsesProxy.
|
||||||
|
*
|
||||||
|
* @param nexusUsesProxy new value of nexusUsesProxy
|
||||||
|
*/
|
||||||
|
public void setNexusUsesProxy(boolean nexusUsesProxy) {
|
||||||
|
this.nexusUsesProxy = nexusUsesProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The database driver name; such as org.h2.Driver.
|
||||||
|
*/
|
||||||
|
private String databaseDriverName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of databaseDriverName.
|
||||||
|
*
|
||||||
|
* @return the value of databaseDriverName
|
||||||
|
*/
|
||||||
|
public String getDatabaseDriverName() {
|
||||||
|
return databaseDriverName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of databaseDriverName.
|
||||||
|
*
|
||||||
|
* @param databaseDriverName new value of databaseDriverName
|
||||||
|
*/
|
||||||
|
public void setDatabaseDriverName(String databaseDriverName) {
|
||||||
|
this.databaseDriverName = databaseDriverName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path to the database driver JAR file if it is not on the class path.
|
||||||
|
*/
|
||||||
|
private String databaseDriverPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of databaseDriverPath.
|
||||||
|
*
|
||||||
|
* @return the value of databaseDriverPath
|
||||||
|
*/
|
||||||
|
public String getDatabaseDriverPath() {
|
||||||
|
return databaseDriverPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of databaseDriverPath.
|
||||||
|
*
|
||||||
|
* @param databaseDriverPath new value of databaseDriverPath
|
||||||
|
*/
|
||||||
|
public void setDatabaseDriverPath(String databaseDriverPath) {
|
||||||
|
this.databaseDriverPath = databaseDriverPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The database connection string.
|
||||||
|
*/
|
||||||
|
private String connectionString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of connectionString.
|
||||||
|
*
|
||||||
|
* @return the value of connectionString
|
||||||
|
*/
|
||||||
|
public String getConnectionString() {
|
||||||
|
return connectionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of connectionString.
|
||||||
|
*
|
||||||
|
* @param connectionString new value of connectionString
|
||||||
|
*/
|
||||||
|
public void setConnectionString(String connectionString) {
|
||||||
|
this.connectionString = connectionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user name for connecting to the database.
|
||||||
|
*/
|
||||||
|
private String databaseUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of databaseUser.
|
||||||
|
*
|
||||||
|
* @return the value of databaseUser
|
||||||
|
*/
|
||||||
|
public String getDatabaseUser() {
|
||||||
|
return databaseUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of databaseUser.
|
||||||
|
*
|
||||||
|
* @param databaseUser new value of databaseUser
|
||||||
|
*/
|
||||||
|
public void setDatabaseUser(String databaseUser) {
|
||||||
|
this.databaseUser = databaseUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The password to use when connecting to the database.
|
||||||
|
*/
|
||||||
|
private String databasePassword;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of databasePassword.
|
||||||
|
*
|
||||||
|
* @return the value of databasePassword
|
||||||
|
*/
|
||||||
|
public String getDatabasePassword() {
|
||||||
|
return databasePassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of databasePassword.
|
||||||
|
*
|
||||||
|
* @param databasePassword new value of databasePassword
|
||||||
|
*/
|
||||||
|
public void setDatabasePassword(String databasePassword) {
|
||||||
|
this.databasePassword = databasePassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additional ZIP File extensions to add analyze. This should be a comma-separated list of file extensions to treat
|
||||||
|
* like ZIP files.
|
||||||
|
*/
|
||||||
|
private String zipExtensions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of zipExtensions.
|
||||||
|
*
|
||||||
|
* @return the value of zipExtensions
|
||||||
|
*/
|
||||||
|
public String getZipExtensions() {
|
||||||
|
return zipExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of zipExtensions.
|
||||||
|
*
|
||||||
|
* @param zipExtensions new value of zipExtensions
|
||||||
|
*/
|
||||||
|
public void setZipExtensions(String zipExtensions) {
|
||||||
|
this.zipExtensions = zipExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The url for the modified NVD CVE (1.2 schema).
|
||||||
|
*/
|
||||||
|
private String cveUrl12Modified;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of cveUrl12Modified.
|
||||||
|
*
|
||||||
|
* @return the value of cveUrl12Modified
|
||||||
|
*/
|
||||||
|
public String getCveUrl12Modified() {
|
||||||
|
return cveUrl12Modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of cveUrl12Modified.
|
||||||
|
*
|
||||||
|
* @param cveUrl12Modified new value of cveUrl12Modified
|
||||||
|
*/
|
||||||
|
public void setCveUrl12Modified(String cveUrl12Modified) {
|
||||||
|
this.cveUrl12Modified = cveUrl12Modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The url for the modified NVD CVE (2.0 schema).
|
||||||
|
*/
|
||||||
|
private String cveUrl20Modified;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of cveUrl20Modified.
|
||||||
|
*
|
||||||
|
* @return the value of cveUrl20Modified
|
||||||
|
*/
|
||||||
|
public String getCveUrl20Modified() {
|
||||||
|
return cveUrl20Modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of cveUrl20Modified.
|
||||||
|
*
|
||||||
|
* @param cveUrl20Modified new value of cveUrl20Modified
|
||||||
|
*/
|
||||||
|
public void setCveUrl20Modified(String cveUrl20Modified) {
|
||||||
|
this.cveUrl20Modified = cveUrl20Modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base Data Mirror URL for CVE 1.2.
|
||||||
|
*/
|
||||||
|
private String cveUrl12Base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of cveUrl12Base.
|
||||||
|
*
|
||||||
|
* @return the value of cveUrl12Base
|
||||||
|
*/
|
||||||
|
public String getCveUrl12Base() {
|
||||||
|
return cveUrl12Base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of cveUrl12Base.
|
||||||
|
*
|
||||||
|
* @param cveUrl12Base new value of cveUrl12Base
|
||||||
|
*/
|
||||||
|
public void setCveUrl12Base(String cveUrl12Base) {
|
||||||
|
this.cveUrl12Base = cveUrl12Base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Mirror URL for CVE 2.0.
|
||||||
|
*/
|
||||||
|
private String cveUrl20Base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of cveUrl20Base.
|
||||||
|
*
|
||||||
|
* @return the value of cveUrl20Base
|
||||||
|
*/
|
||||||
|
public String getCveUrl20Base() {
|
||||||
|
return cveUrl20Base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of cveUrl20Base.
|
||||||
|
*
|
||||||
|
* @param cveUrl20Base new value of cveUrl20Base
|
||||||
|
*/
|
||||||
|
public void setCveUrl20Base(String cveUrl20Base) {
|
||||||
|
this.cveUrl20Base = cveUrl20Base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path to Mono for .NET assembly analysis on non-windows systems.
|
||||||
|
*/
|
||||||
|
private String pathToMono;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of pathToMono.
|
||||||
|
*
|
||||||
|
* @return the value of pathToMono
|
||||||
|
*/
|
||||||
|
public String getPathToMono() {
|
||||||
|
return pathToMono;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of pathToMono.
|
||||||
|
*
|
||||||
|
* @param pathToMono new value of pathToMono
|
||||||
|
*/
|
||||||
|
public void setPathToMono(String pathToMono) {
|
||||||
|
this.pathToMono = pathToMono;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the Dependency-Check on the dependent libraries.
|
||||||
|
*
|
||||||
|
* @return the Engine used to scan the dependencies.
|
||||||
|
* @throws org.owasp.dependencycheck.data.nvdcve.DatabaseException thrown if there is an exception connecting to the
|
||||||
|
* database
|
||||||
|
*/
|
||||||
|
private Engine executeDependencyCheck() throws DatabaseException {
|
||||||
|
populateSettings();
|
||||||
|
Engine engine = null;
|
||||||
|
try {
|
||||||
|
engine = new Engine();
|
||||||
|
engine.setDependencies(this.dependencies);
|
||||||
|
engine.analyzeDependencies();
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (engine != null) {
|
||||||
|
engine.cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return engine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the reports for a given dependency-check engine.
|
||||||
|
*
|
||||||
|
* @param engine a dependency-check engine
|
||||||
|
* @param outDirectory the directory to write the reports to
|
||||||
|
*/
|
||||||
|
private void generateExternalReports(Engine engine, File outDirectory) {
|
||||||
|
DatabaseProperties prop = null;
|
||||||
|
CveDB cve = null;
|
||||||
|
try {
|
||||||
|
cve = new CveDB();
|
||||||
|
cve.open();
|
||||||
|
prop = cve.getDatabaseProperties();
|
||||||
|
} catch (DatabaseException ex) {
|
||||||
|
Logger.getLogger(DependencyCheckScanAgent.class.getName()).log(Level.FINE, "Unable to retrieve DB Properties", ex);
|
||||||
|
} finally {
|
||||||
|
if (cve != null) {
|
||||||
|
cve.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final ReportGenerator r = new ReportGenerator(this.applicationName, engine.getDependencies(), engine.getAnalyzers(), prop);
|
||||||
|
try {
|
||||||
|
r.generateReports(outDirectory.getCanonicalPath(), this.reportFormat.name());
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Logger.getLogger(DependencyCheckScanAgent.class.getName()).log(Level.SEVERE,
|
||||||
|
"Unexpected exception occurred during analysis; please see the verbose error log for more details.");
|
||||||
|
Logger.getLogger(DependencyCheckScanAgent.class.getName()).log(Level.FINE, null, ex);
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
Logger.getLogger(DependencyCheckScanAgent.class.getName()).log(Level.SEVERE,
|
||||||
|
"Unexpected exception occurred during analysis; please see the verbose error log for more details.");
|
||||||
|
Logger.getLogger(DependencyCheckScanAgent.class.getName()).log(Level.FINE, null, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
private void populateSettings() {
|
||||||
|
if (dataDirectory != null) {
|
||||||
|
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
|
||||||
|
} else {
|
||||||
|
final File jarPath = new File(DependencyCheckScanAgent.class.getProtectionDomain().getCodeSource().getLocation().getPath());
|
||||||
|
final File base = jarPath.getParentFile();
|
||||||
|
final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
|
||||||
|
final File dataDir = new File(base, sub);
|
||||||
|
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 (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);
|
||||||
|
}
|
||||||
|
if (suppressionFile != null && !suppressionFile.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
|
||||||
|
}
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
|
||||||
|
if (nexusUrl != null && !nexusUrl.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
|
||||||
|
}
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy);
|
||||||
|
if (databaseDriverName != null && !databaseDriverName.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
|
||||||
|
}
|
||||||
|
if (databaseDriverPath != null && !databaseDriverPath.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
|
||||||
|
}
|
||||||
|
if (connectionString != null && !connectionString.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
|
||||||
|
}
|
||||||
|
if (databaseUser != null && !databaseUser.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.DB_USER, databaseUser);
|
||||||
|
}
|
||||||
|
if (databasePassword != null && !databasePassword.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword);
|
||||||
|
}
|
||||||
|
if (zipExtensions != null && !zipExtensions.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
|
||||||
|
}
|
||||||
|
if (cveUrl12Modified != null && !cveUrl12Modified.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
|
||||||
|
}
|
||||||
|
if (cveUrl20Modified != null && !cveUrl20Modified.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
|
||||||
|
}
|
||||||
|
if (cveUrl12Base != null && !cveUrl12Base.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
|
||||||
|
}
|
||||||
|
if (cveUrl20Base != null && !cveUrl20Base.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
|
||||||
|
}
|
||||||
|
if (pathToMono != null && !pathToMono.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the dependency-check and generates the report.
|
||||||
|
*
|
||||||
|
* @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if there is an exception executing the
|
||||||
|
* scan.
|
||||||
|
*/
|
||||||
|
public void execute() throws ScanAgentException {
|
||||||
|
Engine engine = null;
|
||||||
|
try {
|
||||||
|
engine = executeDependencyCheck();
|
||||||
|
generateExternalReports(engine, new File(this.reportOutputDirectory));
|
||||||
|
if (this.showSummary) {
|
||||||
|
showSummary(engine.getDependencies());
|
||||||
|
}
|
||||||
|
if (this.failBuildOnCVSS <= 10) {
|
||||||
|
checkForFailure(engine.getDependencies());
|
||||||
|
}
|
||||||
|
} catch (DatabaseException ex) {
|
||||||
|
Logger.getLogger(DependencyCheckScanAgent.class.getName()).log(Level.SEVERE,
|
||||||
|
"Unable to connect to the dependency-check database; analysis has stopped");
|
||||||
|
Logger.getLogger(DependencyCheckScanAgent.class.getName()).log(Level.FINE, "", ex);
|
||||||
|
} finally {
|
||||||
|
if (engine != null) {
|
||||||
|
engine.cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the
|
||||||
|
* configuration.
|
||||||
|
*
|
||||||
|
* @param dependencies the list of dependency objects
|
||||||
|
* @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if there is an exception executing the
|
||||||
|
* scan.
|
||||||
|
*/
|
||||||
|
private void checkForFailure(List<Dependency> dependencies) throws ScanAgentException {
|
||||||
|
final StringBuilder ids = new StringBuilder();
|
||||||
|
for (Dependency d : dependencies) {
|
||||||
|
boolean addName = true;
|
||||||
|
for (Vulnerability v : d.getVulnerabilities()) {
|
||||||
|
if (v.getCvssScore() >= failBuildOnCVSS) {
|
||||||
|
if (addName) {
|
||||||
|
addName = false;
|
||||||
|
ids.append(NEW_LINE).append(d.getFileName()).append(": ");
|
||||||
|
ids.append(v.getName());
|
||||||
|
} else {
|
||||||
|
ids.append(", ").append(v.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ids.length() > 0) {
|
||||||
|
final String msg = String.format("%n%nDependency-Check Failure:%n"
|
||||||
|
+ "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n"
|
||||||
|
+ "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString());
|
||||||
|
|
||||||
|
throw new ScanAgentException(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries.
|
||||||
|
*
|
||||||
|
* @param dependencies a list of dependency objects
|
||||||
|
*/
|
||||||
|
private void showSummary(List<Dependency> dependencies) {
|
||||||
|
final StringBuilder summary = new StringBuilder();
|
||||||
|
for (Dependency d : dependencies) {
|
||||||
|
boolean firstEntry = true;
|
||||||
|
final StringBuilder ids = new StringBuilder();
|
||||||
|
for (Vulnerability v : d.getVulnerabilities()) {
|
||||||
|
if (firstEntry) {
|
||||||
|
firstEntry = false;
|
||||||
|
} else {
|
||||||
|
ids.append(", ");
|
||||||
|
}
|
||||||
|
ids.append(v.getName());
|
||||||
|
}
|
||||||
|
if (ids.length() > 0) {
|
||||||
|
summary.append(d.getFileName()).append(" (");
|
||||||
|
firstEntry = true;
|
||||||
|
for (Identifier id : d.getIdentifiers()) {
|
||||||
|
if (firstEntry) {
|
||||||
|
firstEntry = false;
|
||||||
|
} else {
|
||||||
|
summary.append(", ");
|
||||||
|
}
|
||||||
|
summary.append(id.getValue());
|
||||||
|
}
|
||||||
|
summary.append(") : ").append(ids).append(NEW_LINE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (summary.length() > 0) {
|
||||||
|
final String msg = String.format("%n%n"
|
||||||
|
+ "One or more dependencies were identified with known vulnerabilities:%n%n%s"
|
||||||
|
+ "%n%nSee the dependency-check report for more details.%n%n", summary.toString());
|
||||||
|
Logger.getLogger(DependencyCheckScanAgent.class.getName()).log(Level.WARNING, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* <html>
|
||||||
|
* <head>
|
||||||
|
* <title>org.owasp.dependencycheck.agent</title>
|
||||||
|
* </head>
|
||||||
|
* <body>
|
||||||
|
* The agent package holds an agent API that can be used by other applications that have information about dependencies;
|
||||||
|
* but would rather implement something in their code directly rather then spawn a process to run the entire
|
||||||
|
* dependency-check engine. This basically provides programmatic access to running a scan.
|
||||||
|
* </body>
|
||||||
|
* </html>
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.agent;
|
||||||
@@ -17,33 +17,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractAnalyzer implements Analyzer {
|
public abstract class AbstractAnalyzer implements Analyzer {
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility method to help in the creation of the extensions set. This constructs a new Set that can be used in a
|
|
||||||
* final static declaration.<br/><br/>
|
|
||||||
*
|
|
||||||
* This implementation was copied from
|
|
||||||
* http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction
|
|
||||||
*
|
|
||||||
* @param strings a list of strings to add to the set.
|
|
||||||
* @return a Set of strings.
|
|
||||||
*/
|
|
||||||
protected static Set<String> newHashSet(String... strings) {
|
|
||||||
final Set<String> set = new HashSet<String>();
|
|
||||||
|
|
||||||
Collections.addAll(set, strings);
|
|
||||||
return set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The initialize method does nothing for this Analyzer.
|
* The initialize method does nothing for this Analyzer.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,229 @@
|
|||||||
|
/*
|
||||||
|
* 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) 2014 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base FileTypeAnalyzer that all analyzers that have specific file types they analyze should extend.
|
||||||
|
*
|
||||||
|
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||||
|
*/
|
||||||
|
public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implements FileTypeAnalyzer {
|
||||||
|
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="Constructor">
|
||||||
|
/**
|
||||||
|
* Base constructor that all children must call. This checks the configuration to determine if the analyzer is
|
||||||
|
* enabled.
|
||||||
|
*/
|
||||||
|
public AbstractFileTypeAnalyzer() {
|
||||||
|
final String key = getAnalyzerEnabledSettingKey();
|
||||||
|
try {
|
||||||
|
enabled = Settings.getBoolean(key, true);
|
||||||
|
} catch (InvalidSettingException ex) {
|
||||||
|
String msg = String.format("Invalid settting for property '%s'", key);
|
||||||
|
LOGGER.log(Level.WARNING, msg);
|
||||||
|
LOGGER.log(Level.FINE, "", ex);
|
||||||
|
msg = String.format("%s has been disabled", getName());
|
||||||
|
LOGGER.log(Level.WARNING, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//</editor-fold>
|
||||||
|
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="Field defentitions">
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(AbstractFileTypeAnalyzer.class.getName());
|
||||||
|
/**
|
||||||
|
* Whether the file type analyzer detected any files it needs to analyze.
|
||||||
|
*/
|
||||||
|
private boolean filesMatched = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports.
|
||||||
|
*
|
||||||
|
* @return the value of filesMatched
|
||||||
|
*/
|
||||||
|
protected boolean isFilesMatched() {
|
||||||
|
return filesMatched;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports.
|
||||||
|
*
|
||||||
|
* @param filesMatched new value of filesMatched
|
||||||
|
*/
|
||||||
|
protected void setFilesMatched(boolean filesMatched) {
|
||||||
|
this.filesMatched = filesMatched;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag indicating whether or not the analyzer is enabled.
|
||||||
|
*/
|
||||||
|
private boolean enabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of enabled.
|
||||||
|
*
|
||||||
|
* @return the value of enabled
|
||||||
|
*/
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of enabled.
|
||||||
|
*
|
||||||
|
* @param enabled new value of enabled
|
||||||
|
*/
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
//</editor-fold>
|
||||||
|
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="Abstract methods children must implement">
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Returns a list of supported file extensions. An example would be an analyzer that inspected java jar files. The
|
||||||
|
* getSupportedExtensions function would return a set with a single element "jar".</p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* <b>Note:</b> when implementing this the extensions returned MUST be lowercase.</p>
|
||||||
|
*
|
||||||
|
* @return The file extensions supported by this analyzer.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* If the analyzer returns null it will not cause additional files to be analyzed but will be executed against every
|
||||||
|
* file loaded</p>
|
||||||
|
*/
|
||||||
|
protected abstract Set<String> getSupportedExtensions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the file type analyzer.
|
||||||
|
*
|
||||||
|
* @throws Exception thrown if there is an exception during initialization
|
||||||
|
*/
|
||||||
|
protected abstract void initializeFileTypeAnalyzer() throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted,
|
||||||
|
* scanned, and added to the list of dependencies within the engine.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency to analyze
|
||||||
|
* @param engine the engine scanning
|
||||||
|
* @throws AnalysisException thrown if there is an analysis exception
|
||||||
|
*/
|
||||||
|
protected abstract void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Returns the setting key to determine if the analyzer is enabled.</p>
|
||||||
|
*
|
||||||
|
* @return the key for the analyzer's enabled property
|
||||||
|
*/
|
||||||
|
protected abstract String getAnalyzerEnabledSettingKey();
|
||||||
|
|
||||||
|
//</editor-fold>
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="Final implementations for the Analyzer interface">
|
||||||
|
/**
|
||||||
|
* Initializes the analyzer.
|
||||||
|
*
|
||||||
|
* @throws Exception thrown if there is an exception during initialization
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void initialize() throws Exception {
|
||||||
|
if (filesMatched) {
|
||||||
|
initializeFileTypeAnalyzer();
|
||||||
|
} else {
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted,
|
||||||
|
* scanned, and added to the list of dependencies within the engine.
|
||||||
|
*
|
||||||
|
* @param dependency the dependency to analyze
|
||||||
|
* @param engine the engine scanning
|
||||||
|
* @throws AnalysisException thrown if there is an analysis exception
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
|
if (enabled) {
|
||||||
|
analyzeFileType(dependency, engine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not this analyzer can process the given extension.
|
||||||
|
*
|
||||||
|
* @param extension the file extension to test for support.
|
||||||
|
* @return whether or not the specified file extension is supported by this analyzer.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final boolean supportsExtension(String extension) {
|
||||||
|
if (!enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final Set<String> ext = getSupportedExtensions();
|
||||||
|
if (ext == null) {
|
||||||
|
final String msg = String.format("The '%s' analyzer is misconfigured and does not have any file extensions;"
|
||||||
|
+ " it will be disabled", getName());
|
||||||
|
Logger.getLogger(AbstractFileTypeAnalyzer.class.getName()).log(Level.SEVERE, msg);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
final boolean match = ext.contains(extension);
|
||||||
|
if (match) {
|
||||||
|
filesMatched = match;
|
||||||
|
}
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//</editor-fold>
|
||||||
|
|
||||||
|
//<editor-fold defaultstate="collapsed" desc="Static utility methods">
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Utility method to help in the creation of the extensions set. This constructs a new Set that can be used in a
|
||||||
|
* final static declaration.</p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This implementation was copied from
|
||||||
|
* http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction</p>
|
||||||
|
*
|
||||||
|
* @param strings a list of strings to add to the set.
|
||||||
|
* @return a Set of strings.
|
||||||
|
*/
|
||||||
|
protected static Set<String> newHashSet(String... strings) {
|
||||||
|
final Set<String> set = new HashSet<String>();
|
||||||
|
|
||||||
|
Collections.addAll(set, strings);
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
//</editor-fold>
|
||||||
|
}
|
||||||
@@ -18,13 +18,20 @@
|
|||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import org.owasp.dependencycheck.suppression.SuppressionParseException;
|
import org.owasp.dependencycheck.suppression.SuppressionParseException;
|
||||||
import org.owasp.dependencycheck.suppression.SuppressionParser;
|
import org.owasp.dependencycheck.suppression.SuppressionParser;
|
||||||
import org.owasp.dependencycheck.suppression.SuppressionRule;
|
import org.owasp.dependencycheck.suppression.SuppressionRule;
|
||||||
|
import org.owasp.dependencycheck.utils.DownloadFailedException;
|
||||||
|
import org.owasp.dependencycheck.utils.Downloader;
|
||||||
|
import org.owasp.dependencycheck.utils.FileUtils;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,17 +51,6 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this analyzer can process the given extension.
|
|
||||||
*
|
|
||||||
* @param extension the file extension to test for support.
|
|
||||||
* @return whether or not the specified file extension is supported by this analyzer.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
/**
|
/**
|
||||||
* The initialize method loads the suppression XML file.
|
* The initialize method loads the suppression XML file.
|
||||||
@@ -95,17 +91,58 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
|
|||||||
* @throws SuppressionParseException thrown if the XML cannot be parsed.
|
* @throws SuppressionParseException thrown if the XML cannot be parsed.
|
||||||
*/
|
*/
|
||||||
private void loadSuppressionData() throws SuppressionParseException {
|
private void loadSuppressionData() throws SuppressionParseException {
|
||||||
final File file = Settings.getFile(Settings.KEYS.SUPPRESSION_FILE);
|
final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE);
|
||||||
if (file != null) {
|
if (suppressionFilePath == null) {
|
||||||
final SuppressionParser parser = new SuppressionParser();
|
return;
|
||||||
try {
|
}
|
||||||
rules = parser.parseSuppressionRules(file);
|
File file = null;
|
||||||
} catch (SuppressionParseException ex) {
|
boolean deleteTempFile = false;
|
||||||
final String msg = String.format("Unable to parse suppression xml file '%s'", file.getPath());
|
try {
|
||||||
Logger.getLogger(AbstractSuppressionAnalyzer.class.getName()).log(Level.WARNING, msg);
|
final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE);
|
||||||
Logger.getLogger(AbstractSuppressionAnalyzer.class.getName()).log(Level.WARNING, ex.getMessage());
|
if (uriRx.matcher(suppressionFilePath).matches()) {
|
||||||
Logger.getLogger(AbstractSuppressionAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
deleteTempFile = true;
|
||||||
throw ex;
|
file = FileUtils.getTempFile("suppression", "xml");
|
||||||
|
final URL url = new URL(suppressionFilePath);
|
||||||
|
try {
|
||||||
|
Downloader.fetchFile(url, file, false);
|
||||||
|
} catch (DownloadFailedException ex) {
|
||||||
|
Downloader.fetchFile(url, file, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
file = new File(suppressionFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file != null) {
|
||||||
|
final SuppressionParser parser = new SuppressionParser();
|
||||||
|
try {
|
||||||
|
rules = parser.parseSuppressionRules(file);
|
||||||
|
Logger.getLogger(AbstractSuppressionAnalyzer.class.getName()).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());
|
||||||
|
Logger.getLogger(AbstractSuppressionAnalyzer.class.getName()).log(Level.WARNING, msg);
|
||||||
|
Logger.getLogger(AbstractSuppressionAnalyzer.class.getName()).log(Level.WARNING, ex.getMessage());
|
||||||
|
Logger.getLogger(AbstractSuppressionAnalyzer.class.getName()).log(Level.FINE, "", ex);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DownloadFailedException ex) {
|
||||||
|
Logger.getLogger(AbstractSuppressionAnalyzer.class.getName()).log(Level.WARNING,
|
||||||
|
"Unable to fetch the configured suppression file");
|
||||||
|
Logger.getLogger(AbstractSuppressionAnalyzer.class.getName()).log(Level.FINE, "", ex);
|
||||||
|
throw new SuppressionParseException("Unable to fetch the configured suppression file", ex);
|
||||||
|
} catch (MalformedURLException ex) {
|
||||||
|
Logger.getLogger(AbstractSuppressionAnalyzer.class.getName()).log(Level.WARNING,
|
||||||
|
"Configured suppression file has an invalid URL");
|
||||||
|
Logger.getLogger(AbstractSuppressionAnalyzer.class.getName()).log(Level.FINE, "", ex);
|
||||||
|
throw new SuppressionParseException("Configured suppression file has an invalid URL", ex);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Logger.getLogger(AbstractSuppressionAnalyzer.class.getName()).log(Level.WARNING,
|
||||||
|
"Unable to create temp file for suppressions");
|
||||||
|
Logger.getLogger(AbstractSuppressionAnalyzer.class.getName()).log(Level.FINE, "", ex);
|
||||||
|
throw new SuppressionParseException("Unable to create temp file for suppressions", ex);
|
||||||
|
} finally {
|
||||||
|
if (deleteTempFile && file != null) {
|
||||||
|
FileUtils.delete(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,22 +41,6 @@ public interface Analyzer {
|
|||||||
*/
|
*/
|
||||||
void analyze(Dependency dependency, Engine engine) throws AnalysisException;
|
void analyze(Dependency dependency, Engine engine) throws AnalysisException;
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Returns a list of supported file extensions. An example would be an analyzer that inspected java jar files. The
|
|
||||||
* getSupportedExtensions function would return a set with a single element "jar".</p>
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* <b>Note:</b> when implementing this the extensions returned MUST be lowercase.</p>
|
|
||||||
*
|
|
||||||
* @return The file extensions supported by this analyzer.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* If the analyzer returns null it will not cause additional files to be analyzed but will be executed against every
|
|
||||||
* file loaded</p>
|
|
||||||
*/
|
|
||||||
Set<String> getSupportedExtensions();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the analyzer.
|
* Returns the name of the analyzer.
|
||||||
*
|
*
|
||||||
@@ -65,14 +48,6 @@ public interface Analyzer {
|
|||||||
*/
|
*/
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this analyzer can process the given extension.
|
|
||||||
*
|
|
||||||
* @param extension the file extension to test for support.
|
|
||||||
* @return whether or not the specified file extension is supported by this analyzer.
|
|
||||||
*/
|
|
||||||
boolean supportsExtension(String extension);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the phase that the analyzer is intended to run in.
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -53,8 +53,12 @@ import org.owasp.dependencycheck.utils.Settings;
|
|||||||
*
|
*
|
||||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||||
*/
|
*/
|
||||||
public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(ArchiveAnalyzer.class.getName());
|
||||||
/**
|
/**
|
||||||
* The buffer size to use when extracting files from the archive.
|
* The buffer size to use when extracting files from the archive.
|
||||||
*/
|
*/
|
||||||
@@ -75,6 +79,7 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
* Tracks the current scan/extraction depth for nested archives.
|
* Tracks the current scan/extraction depth for nested archives.
|
||||||
*/
|
*/
|
||||||
private int scanDepth = 0;
|
private int scanDepth = 0;
|
||||||
|
|
||||||
//<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
|
//<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
|
||||||
/**
|
/**
|
||||||
* The name of the analyzer.
|
* The name of the analyzer.
|
||||||
@@ -108,6 +113,7 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
*
|
*
|
||||||
* @return a list of file EXTENSIONS supported by this analyzer.
|
* @return a list of file EXTENSIONS supported by this analyzer.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Set<String> getSupportedExtensions() {
|
public Set<String> getSupportedExtensions() {
|
||||||
return EXTENSIONS;
|
return EXTENSIONS;
|
||||||
}
|
}
|
||||||
@@ -117,37 +123,39 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
*
|
*
|
||||||
* @return the name of the analyzer.
|
* @return the name of the analyzer.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return ANALYZER_NAME;
|
return ANALYZER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this analyzer can process the given extension.
|
|
||||||
*
|
|
||||||
* @param extension the file extension to test for support.
|
|
||||||
* @return whether or not the specified file extension is supported by this analyzer.
|
|
||||||
*/
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return EXTENSIONS.contains(extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the phase that the analyzer is intended to run in.
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
*
|
*
|
||||||
* @return the phase that the analyzer is intended to run in.
|
* @return the phase that the analyzer is intended to run in.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public AnalysisPhase getAnalysisPhase() {
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
return ANALYSIS_PHASE;
|
return ANALYSIS_PHASE;
|
||||||
}
|
}
|
||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the key used in the properties file to reference the analyzer's enabled property.
|
||||||
|
*
|
||||||
|
* @return the analyzer's enabled property setting key
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_ARCHIVE_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The initialize method does nothing for this Analyzer.
|
* The initialize method does nothing for this Analyzer.
|
||||||
*
|
*
|
||||||
* @throws Exception is thrown if there is an exception deleting or creating temporary files
|
* @throws Exception is thrown if there is an exception deleting or creating temporary files
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void initialize() throws Exception {
|
public void initializeFileTypeAnalyzer() throws Exception {
|
||||||
final File baseDir = Settings.getTempDirectory();
|
final File baseDir = Settings.getTempDirectory();
|
||||||
if (!baseDir.exists()) {
|
if (!baseDir.exists()) {
|
||||||
if (!baseDir.mkdirs()) {
|
if (!baseDir.mkdirs()) {
|
||||||
@@ -174,11 +182,10 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
@Override
|
@Override
|
||||||
public void close() throws Exception {
|
public void close() throws Exception {
|
||||||
if (tempFileLocation != null && tempFileLocation.exists()) {
|
if (tempFileLocation != null && tempFileLocation.exists()) {
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINE, "Attempting to delete temporary files");
|
LOGGER.log(Level.FINE, "Attempting to delete temporary files");
|
||||||
final boolean success = FileUtils.delete(tempFileLocation);
|
final boolean success = FileUtils.delete(tempFileLocation);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.WARNING,
|
LOGGER.log(Level.WARNING, "Failed to delete some temporary files, see the log for more details");
|
||||||
"Failed to delete some temporary files, see the log for more details");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,7 +199,7 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
* @throws AnalysisException thrown if there is an analysis exception
|
* @throws AnalysisException thrown if there is an analysis exception
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
final File f = new File(dependency.getActualFilePath());
|
final File f = new File(dependency.getActualFilePath());
|
||||||
final File tmpDir = getNextTempDirectory();
|
final File tmpDir = getNextTempDirectory();
|
||||||
extractFiles(f, tmpDir, engine);
|
extractFiles(f, tmpDir, engine);
|
||||||
@@ -268,7 +275,7 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
try {
|
try {
|
||||||
fis = new FileInputStream(archive);
|
fis = new FileInputStream(archive);
|
||||||
} catch (FileNotFoundException ex) {
|
} catch (FileNotFoundException ex) {
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
LOGGER.log(Level.FINE, null, ex);
|
||||||
throw new AnalysisException("Archive file was not found.", ex);
|
throw new AnalysisException("Archive file was not found.", ex);
|
||||||
}
|
}
|
||||||
final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase();
|
final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase();
|
||||||
@@ -286,17 +293,17 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
}
|
}
|
||||||
} catch (ArchiveExtractionException ex) {
|
} catch (ArchiveExtractionException ex) {
|
||||||
final String msg = String.format("Exception extracting archive '%s'.", archive.getName());
|
final String msg = String.format("Exception extracting archive '%s'.", archive.getName());
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.WARNING, msg);
|
LOGGER.log(Level.WARNING, msg);
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
LOGGER.log(Level.FINE, null, ex);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
final String msg = String.format("Exception reading archive '%s'.", archive.getName());
|
final String msg = String.format("Exception reading archive '%s'.", archive.getName());
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.WARNING, msg);
|
LOGGER.log(Level.WARNING, msg);
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
LOGGER.log(Level.FINE, null, ex);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
fis.close();
|
fis.close();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINEST, null, ex);
|
LOGGER.log(Level.FINEST, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -375,7 +382,7 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
try {
|
try {
|
||||||
input.close();
|
input.close();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINEST, null, ex);
|
LOGGER.log(Level.FINEST, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -398,17 +405,17 @@ public class ArchiveAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
out.write(buffer, 0, n);
|
out.write(buffer, 0, n);
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException ex) {
|
} catch (FileNotFoundException ex) {
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
LOGGER.log(Level.FINE, null, ex);
|
||||||
throw new ArchiveExtractionException(ex);
|
throw new ArchiveExtractionException(ex);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
LOGGER.log(Level.FINE, null, ex);
|
||||||
throw new ArchiveExtractionException(ex);
|
throw new ArchiveExtractionException(ex);
|
||||||
} finally {
|
} finally {
|
||||||
if (out != null) {
|
if (out != null) {
|
||||||
try {
|
try {
|
||||||
out.close();
|
out.close();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.getLogger(ArchiveAnalyzer.class.getName()).log(Level.FINEST, null, ex);
|
LOGGER.log(Level.FINEST, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,10 +17,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -46,7 +48,7 @@ import org.xml.sax.SAXException;
|
|||||||
* @author colezlaw
|
* @author colezlaw
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class AssemblyAnalyzer extends AbstractAnalyzer {
|
public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The analyzer name
|
* The analyzer name
|
||||||
@@ -63,7 +65,7 @@ public class AssemblyAnalyzer extends AbstractAnalyzer {
|
|||||||
/**
|
/**
|
||||||
* The temp value for GrokAssembly.exe
|
* The temp value for GrokAssembly.exe
|
||||||
*/
|
*/
|
||||||
private File grokAssemblyExe;
|
private File grokAssemblyExe = null;
|
||||||
/**
|
/**
|
||||||
* The DocumentBuilder for parsing the XML
|
* The DocumentBuilder for parsing the XML
|
||||||
*/
|
*/
|
||||||
@@ -71,7 +73,7 @@ public class AssemblyAnalyzer extends AbstractAnalyzer {
|
|||||||
/**
|
/**
|
||||||
* Logger
|
* Logger
|
||||||
*/
|
*/
|
||||||
private static final Logger LOG = Logger.getLogger(AbstractAnalyzer.class.getName());
|
private static final Logger LOG = Logger.getLogger(AssemblyAnalyzer.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the beginnings of a List for ProcessBuilder
|
* Builds the beginnings of a List for ProcessBuilder
|
||||||
@@ -101,7 +103,7 @@ public class AssemblyAnalyzer extends AbstractAnalyzer {
|
|||||||
* @throws AnalysisException if anything goes sideways
|
* @throws AnalysisException if anything goes sideways
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void analyze(Dependency dependency, Engine engine)
|
public void analyzeFileType(Dependency dependency, Engine engine)
|
||||||
throws AnalysisException {
|
throws AnalysisException {
|
||||||
if (grokAssemblyExe == null) {
|
if (grokAssemblyExe == null) {
|
||||||
LOG.warning("GrokAssembly didn't get deployed");
|
LOG.warning("GrokAssembly didn't get deployed");
|
||||||
@@ -111,8 +113,16 @@ public class AssemblyAnalyzer extends AbstractAnalyzer {
|
|||||||
final List<String> args = buildArgumentList();
|
final List<String> args = buildArgumentList();
|
||||||
args.add(dependency.getActualFilePath());
|
args.add(dependency.getActualFilePath());
|
||||||
final ProcessBuilder pb = new ProcessBuilder(args);
|
final ProcessBuilder pb = new ProcessBuilder(args);
|
||||||
|
BufferedReader rdr = null;
|
||||||
try {
|
try {
|
||||||
final Process proc = pb.start();
|
final Process proc = pb.start();
|
||||||
|
// Try evacuating the error stream
|
||||||
|
rdr = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
|
||||||
|
String line = null;
|
||||||
|
while (rdr.ready() && (line = rdr.readLine()) != null) {
|
||||||
|
LOG.log(Level.WARNING, "Error from GrokAssembly: {0}", line);
|
||||||
|
}
|
||||||
|
int rc = 0;
|
||||||
final Document doc = builder.parse(proc.getInputStream());
|
final Document doc = builder.parse(proc.getInputStream());
|
||||||
final XPath xpath = XPathFactory.newInstance().newXPath();
|
final XPath xpath = XPathFactory.newInstance().newXPath();
|
||||||
|
|
||||||
@@ -140,6 +150,18 @@ public class AssemblyAnalyzer extends AbstractAnalyzer {
|
|||||||
product, Confidence.HIGH));
|
product, Confidence.HIGH));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
rc = proc.waitFor();
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (rc == 3) {
|
||||||
|
LOG.log(Level.INFO, "{0} is not a valid assembly", dependency.getActualFilePath());
|
||||||
|
return;
|
||||||
|
} else if (rc != 0) {
|
||||||
|
LOG.log(Level.WARNING, "Return code {0} from GrokAssembly", rc);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
throw new AnalysisException(ioe);
|
throw new AnalysisException(ioe);
|
||||||
} catch (SAXException saxe) {
|
} catch (SAXException saxe) {
|
||||||
@@ -147,6 +169,14 @@ public class AssemblyAnalyzer extends AbstractAnalyzer {
|
|||||||
} catch (XPathExpressionException xpe) {
|
} catch (XPathExpressionException xpe) {
|
||||||
// This shouldn't happen
|
// This shouldn't happen
|
||||||
throw new AnalysisException(xpe);
|
throw new AnalysisException(xpe);
|
||||||
|
} finally {
|
||||||
|
if (rdr != null) {
|
||||||
|
try {
|
||||||
|
rdr.close();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Logger.getLogger(AssemblyAnalyzer.class.getName()).log(Level.FINEST, "ignore", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,9 +186,8 @@ public class AssemblyAnalyzer extends AbstractAnalyzer {
|
|||||||
* @throws Exception if anything goes wrong
|
* @throws Exception if anything goes wrong
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void initialize() throws Exception {
|
public void initializeFileTypeAnalyzer() throws Exception {
|
||||||
super.initialize();
|
final File tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory());
|
||||||
final File tempFile = File.createTempFile("GKA", ".exe");
|
|
||||||
FileOutputStream fos = null;
|
FileOutputStream fos = null;
|
||||||
InputStream is = null;
|
InputStream is = null;
|
||||||
try {
|
try {
|
||||||
@@ -195,8 +224,16 @@ public class AssemblyAnalyzer extends AbstractAnalyzer {
|
|||||||
|
|
||||||
// Now, need to see if GrokAssembly actually runs from this location.
|
// Now, need to see if GrokAssembly actually runs from this location.
|
||||||
final List<String> args = buildArgumentList();
|
final List<String> args = buildArgumentList();
|
||||||
|
BufferedReader rdr = null;
|
||||||
try {
|
try {
|
||||||
final Process p = new ProcessBuilder(args).start();
|
final ProcessBuilder pb = new ProcessBuilder(args);
|
||||||
|
final Process p = pb.start();
|
||||||
|
// Try evacuating the error stream
|
||||||
|
rdr = new BufferedReader(new InputStreamReader(p.getErrorStream()));
|
||||||
|
String line;
|
||||||
|
while (rdr.ready() && (line = rdr.readLine()) != null) {
|
||||||
|
// We expect this to complain
|
||||||
|
}
|
||||||
final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream());
|
final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream());
|
||||||
final XPath xpath = XPathFactory.newInstance().newXPath();
|
final XPath xpath = XPathFactory.newInstance().newXPath();
|
||||||
final String error = xpath.evaluate("/assembly/error", doc);
|
final String error = xpath.evaluate("/assembly/error", doc);
|
||||||
@@ -211,6 +248,14 @@ public class AssemblyAnalyzer extends AbstractAnalyzer {
|
|||||||
+ "this can be ignored unless you are scanning .NET dlls. Please see the log for more details.");
|
+ "this can be ignored unless you are scanning .NET dlls. Please see the log for more details.");
|
||||||
LOG.log(Level.FINE, "Could not execute GrokAssembly {0}", e.getMessage());
|
LOG.log(Level.FINE, "Could not execute GrokAssembly {0}", e.getMessage());
|
||||||
throw new AnalysisException("An error occured with the .NET AssemblyAnalyzer", e);
|
throw new AnalysisException("An error occured with the .NET AssemblyAnalyzer", e);
|
||||||
|
} finally {
|
||||||
|
if (rdr != null) {
|
||||||
|
try {
|
||||||
|
rdr.close();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Logger.getLogger(AssemblyAnalyzer.class.getName()).log(Level.FINEST, "ignore", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||||
@@ -220,7 +265,9 @@ public class AssemblyAnalyzer extends AbstractAnalyzer {
|
|||||||
public void close() throws Exception {
|
public void close() throws Exception {
|
||||||
super.close();
|
super.close();
|
||||||
try {
|
try {
|
||||||
grokAssemblyExe.delete();
|
if (grokAssemblyExe != null && !grokAssemblyExe.delete()) {
|
||||||
|
grokAssemblyExe.deleteOnExit();
|
||||||
|
}
|
||||||
} catch (SecurityException se) {
|
} catch (SecurityException se) {
|
||||||
LOG.fine("Can't delete temporary GrokAssembly.exe");
|
LOG.fine("Can't delete temporary GrokAssembly.exe");
|
||||||
}
|
}
|
||||||
@@ -246,17 +293,6 @@ public class AssemblyAnalyzer extends AbstractAnalyzer {
|
|||||||
return ANALYZER_NAME;
|
return ANALYZER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets whether the analyzer supports the provided extension.
|
|
||||||
*
|
|
||||||
* @param extension the extension to check
|
|
||||||
* @return whether the analyzer supports the extension
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return SUPORTED_EXTENSIONS.contains(extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the phase this analyzer runs under.
|
* Returns the phase this analyzer runs under.
|
||||||
*
|
*
|
||||||
@@ -266,4 +302,14 @@ public class AssemblyAnalyzer extends AbstractAnalyzer {
|
|||||||
public AnalysisPhase getAnalysisPhase() {
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
return ANALYSIS_PHASE;
|
return ANALYSIS_PHASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the key used in the properties file to reference the analyzer's enabled property.
|
||||||
|
*
|
||||||
|
* @return the analyzer's enabled property setting key
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,36 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
*/
|
*/
|
||||||
private CveDB cve;
|
private CveDB cve;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of this analyzer.
|
||||||
|
*
|
||||||
|
* @return the name of this analyzer.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "CPE Analyzer";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the analysis phase that this analyzer should run in.
|
||||||
|
*
|
||||||
|
* @return the analysis phase that this analyzer should run in.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
|
return AnalysisPhase.IDENTIFIER_ANALYSIS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the CPE Lucene Index.
|
||||||
|
*
|
||||||
|
* @throws Exception is thrown if there is an issue opening the index.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void initialize() throws Exception {
|
||||||
|
this.open();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the data source.
|
* Opens the data source.
|
||||||
*
|
*
|
||||||
@@ -461,57 +491,6 @@ public class CPEAnalyzer implements Analyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true because this analyzer supports all dependency types.
|
|
||||||
*
|
|
||||||
* @return true.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Set<String> getSupportedExtensions() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of this analyzer.
|
|
||||||
*
|
|
||||||
* @return the name of this analyzer.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "CPE Analyzer";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true because this analyzer supports all dependency types.
|
|
||||||
*
|
|
||||||
* @param extension the file extension of the dependency being analyzed.
|
|
||||||
* @return true.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the analysis phase that this analyzer should run in.
|
|
||||||
*
|
|
||||||
* @return the analysis phase that this analyzer should run in.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public AnalysisPhase getAnalysisPhase() {
|
|
||||||
return AnalysisPhase.IDENTIFIER_ANALYSIS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens the CPE Lucene Index.
|
|
||||||
*
|
|
||||||
* @throws Exception is thrown if there is an issue opening the index.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void initialize() throws Exception {
|
|
||||||
this.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a list of CPE values from the CveDB based on the vendor and product passed in. The list is then
|
* Retrieves a list of CPE values from the CveDB based on the vendor and product passed in. The list is then
|
||||||
* validated to find only CPEs that are valid for the given dependency. It is possible that the CPE identified is a
|
* validated to find only CPEs that are valid for the given dependency. It is possible that the CPE identified is a
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@@ -28,6 +27,7 @@ import java.util.logging.Logger;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.dependency.Identifier;
|
import org.owasp.dependencycheck.dependency.Identifier;
|
||||||
import org.owasp.dependencycheck.utils.DependencyVersion;
|
import org.owasp.dependencycheck.utils.DependencyVersion;
|
||||||
@@ -57,10 +57,6 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
private boolean analyzed = false;
|
private boolean analyzed = false;
|
||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
//<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
|
//<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
|
||||||
/**
|
|
||||||
* The set of file extensions supported by this analyzer.
|
|
||||||
*/
|
|
||||||
private static final Set<String> EXTENSIONS = null;
|
|
||||||
/**
|
/**
|
||||||
* The name of the analyzer.
|
* The name of the analyzer.
|
||||||
*/
|
*/
|
||||||
@@ -70,15 +66,6 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
*/
|
*/
|
||||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_FINDING_ANALYSIS;
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_FINDING_ANALYSIS;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*
|
|
||||||
* @return a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*/
|
|
||||||
public Set<String> getSupportedExtensions() {
|
|
||||||
return EXTENSIONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the analyzer.
|
* Returns the name of the analyzer.
|
||||||
*
|
*
|
||||||
@@ -88,16 +75,6 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
|
|||||||
return ANALYZER_NAME;
|
return ANALYZER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this analyzer can process the given extension.
|
|
||||||
*
|
|
||||||
* @param extension the file extension to test for support
|
|
||||||
* @return whether or not the specified file extension is supported by this analyzer.
|
|
||||||
*/
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the phase that the analyzer is intended to run in.
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -43,10 +43,6 @@ import org.owasp.dependencycheck.dependency.VulnerableSoftware;
|
|||||||
public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
||||||
|
|
||||||
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
|
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
|
||||||
/**
|
|
||||||
* The set of file extensions supported by this analyzer.
|
|
||||||
*/
|
|
||||||
private static final Set<String> EXTENSIONS = null;
|
|
||||||
/**
|
/**
|
||||||
* The name of the analyzer.
|
* The name of the analyzer.
|
||||||
*/
|
*/
|
||||||
@@ -56,15 +52,6 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
*/
|
*/
|
||||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS;
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*
|
|
||||||
* @return a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*/
|
|
||||||
public Set<String> getSupportedExtensions() {
|
|
||||||
return EXTENSIONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the analyzer.
|
* Returns the name of the analyzer.
|
||||||
*
|
*
|
||||||
@@ -74,16 +61,6 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
return ANALYZER_NAME;
|
return ANALYZER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this analyzer can process the given extension.
|
|
||||||
*
|
|
||||||
* @param extension the file extension to test for support
|
|
||||||
* @return whether or not the specified file extension is supported by this analyzer.
|
|
||||||
*/
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the phase that the analyzer is intended to run in.
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -17,10 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Set;
|
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
import org.owasp.dependencycheck.dependency.Confidence;
|
import org.owasp.dependencycheck.dependency.Confidence;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.utils.DependencyVersion;
|
import org.owasp.dependencycheck.utils.DependencyVersion;
|
||||||
@@ -43,19 +42,6 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
* The phase that this analyzer is intended to run in.
|
* The phase that this analyzer is intended to run in.
|
||||||
*/
|
*/
|
||||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
||||||
/**
|
|
||||||
* The set of file extensions supported by this analyzer.
|
|
||||||
*/
|
|
||||||
private static final Set<String> EXTENSIONS = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*
|
|
||||||
* @return a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*/
|
|
||||||
public Set<String> getSupportedExtensions() {
|
|
||||||
return EXTENSIONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the analyzer.
|
* Returns the name of the analyzer.
|
||||||
@@ -66,16 +52,6 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
return ANALYZER_NAME;
|
return ANALYZER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this analyzer can process the given extension.
|
|
||||||
*
|
|
||||||
* @param extension the file extension to test for support.
|
|
||||||
* @return whether or not the specified file extension is supported by this analyzer.
|
|
||||||
*/
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the phase that the analyzer is intended to run in.
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* 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) 2014 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Analyzer that scans specific file types.
|
||||||
|
*
|
||||||
|
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||||
|
*/
|
||||||
|
public interface FileTypeAnalyzer extends Analyzer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not this analyzer can process the given extension.
|
||||||
|
*
|
||||||
|
* @param extension the file extension to test for support.
|
||||||
|
* @return whether or not the specified file extension is supported by this analyzer.
|
||||||
|
*/
|
||||||
|
boolean supportsExtension(String extension);
|
||||||
|
}
|
||||||
@@ -17,11 +17,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
import org.owasp.dependencycheck.dependency.Confidence;
|
import org.owasp.dependencycheck.dependency.Confidence;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.dependency.Evidence;
|
import org.owasp.dependencycheck.dependency.Evidence;
|
||||||
@@ -41,44 +41,23 @@ public class HintAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
* The phase that this analyzer is intended to run in.
|
* The phase that this analyzer is intended to run in.
|
||||||
*/
|
*/
|
||||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_IDENTIFIER_ANALYSIS;
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_IDENTIFIER_ANALYSIS;
|
||||||
/**
|
|
||||||
* The set of file extensions supported by this analyzer.
|
|
||||||
*/
|
|
||||||
private static final Set<String> EXTENSIONS = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*
|
|
||||||
* @return a list of file EXTENSIONS supported by this analyzer.
|
|
||||||
*/
|
|
||||||
public Set<String> getSupportedExtensions() {
|
|
||||||
return EXTENSIONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the analyzer.
|
* Returns the name of the analyzer.
|
||||||
*
|
*
|
||||||
* @return the name of the analyzer.
|
* @return the name of the analyzer.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return ANALYZER_NAME;
|
return ANALYZER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this analyzer can process the given extension.
|
|
||||||
*
|
|
||||||
* @param extension the file extension to test for support.
|
|
||||||
* @return whether or not the specified file extension is supported by this analyzer.
|
|
||||||
*/
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the phase that the analyzer is intended to run in.
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
*
|
*
|
||||||
* @return the phase that the analyzer is intended to run in.
|
* @return the phase that the analyzer is intended to run in.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public AnalysisPhase getAnalysisPhase() {
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
return ANALYSIS_PHASE;
|
return ANALYSIS_PHASE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,9 +79,13 @@ import org.xml.sax.XMLReader;
|
|||||||
*
|
*
|
||||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||||
*/
|
*/
|
||||||
public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
|
||||||
//<editor-fold defaultstate="collapsed" desc="Constants and Member Variables">
|
//<editor-fold defaultstate="collapsed" desc="Constants and Member Variables">
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(JarAnalyzer.class.getName());
|
||||||
/**
|
/**
|
||||||
* The buffer size to use when extracting files from the archive.
|
* The buffer size to use when extracting files from the archive.
|
||||||
*/
|
*/
|
||||||
@@ -111,9 +115,15 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
"buildjdk",
|
"buildjdk",
|
||||||
"ant-version",
|
"ant-version",
|
||||||
"antversion",
|
"antversion",
|
||||||
|
"dynamicimportpackage",
|
||||||
|
"dynamicimport-package",
|
||||||
|
"dynamic-importpackage",
|
||||||
|
"dynamic-import-package",
|
||||||
"import-package",
|
"import-package",
|
||||||
|
"ignore-package",
|
||||||
"export-package",
|
"export-package",
|
||||||
"importpackage",
|
"importpackage",
|
||||||
|
"ignorepackage",
|
||||||
"exportpackage",
|
"exportpackage",
|
||||||
"sealed",
|
"sealed",
|
||||||
"manifest-version",
|
"manifest-version",
|
||||||
@@ -125,7 +135,10 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
"tool",
|
"tool",
|
||||||
"bundle-manifestversion",
|
"bundle-manifestversion",
|
||||||
"bundlemanifestversion",
|
"bundlemanifestversion",
|
||||||
"include-resource");
|
"include-resource",
|
||||||
|
"embed-dependency",
|
||||||
|
"ipojo-components",
|
||||||
|
"ipojo-extension");
|
||||||
/**
|
/**
|
||||||
* item in some manifest, should be considered medium confidence.
|
* item in some manifest, should be considered medium confidence.
|
||||||
*/
|
*/
|
||||||
@@ -160,10 +173,11 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
final JAXBContext jaxbContext = JAXBContext.newInstance("org.owasp.dependencycheck.jaxb.pom.generated");
|
final JAXBContext jaxbContext = JAXBContext.newInstance("org.owasp.dependencycheck.jaxb.pom.generated");
|
||||||
pomUnmarshaller = jaxbContext.createUnmarshaller();
|
pomUnmarshaller = jaxbContext.createUnmarshaller();
|
||||||
} catch (JAXBException ex) { //guess we will just have a null pointer exception later...
|
} catch (JAXBException ex) { //guess we will just have a null pointer exception later...
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.SEVERE, "Unable to load parser. See the log for more details.");
|
LOGGER.log(Level.SEVERE, "Unable to load parser. See the log for more details.");
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
LOGGER.log(Level.FINE, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
|
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
|
||||||
/**
|
/**
|
||||||
* The name of the analyzer.
|
* The name of the analyzer.
|
||||||
@@ -183,6 +197,7 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
*
|
*
|
||||||
* @return a list of file EXTENSIONS supported by this analyzer.
|
* @return a list of file EXTENSIONS supported by this analyzer.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Set<String> getSupportedExtensions() {
|
public Set<String> getSupportedExtensions() {
|
||||||
return EXTENSIONS;
|
return EXTENSIONS;
|
||||||
}
|
}
|
||||||
@@ -192,20 +207,11 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
*
|
*
|
||||||
* @return the name of the analyzer.
|
* @return the name of the analyzer.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return ANALYZER_NAME;
|
return ANALYZER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this analyzer can process the given extension.
|
|
||||||
*
|
|
||||||
* @param extension the file extension to test for support.
|
|
||||||
* @return whether or not the specified file extension is supported by this analyzer.
|
|
||||||
*/
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return EXTENSIONS.contains(extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the phase that the analyzer is intended to run in.
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
*
|
*
|
||||||
@@ -216,6 +222,16 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
}
|
}
|
||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the key used in the properties file to reference the analyzer's enabled property.
|
||||||
|
*
|
||||||
|
* @return the analyzer's enabled property setting key
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_JAR_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a specified JAR file and collects information from the manifest and checksums to identify the correct CPE
|
* Loads a specified JAR file and collects information from the manifest and checksums to identify the correct CPE
|
||||||
* information.
|
* information.
|
||||||
@@ -225,7 +241,7 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
* @throws AnalysisException is thrown if there is an error reading the JAR file.
|
* @throws AnalysisException is thrown if there is an error reading the JAR file.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
try {
|
try {
|
||||||
final ArrayList<ClassNameInformation> classNames = collectClassNames(dependency);
|
final ArrayList<ClassNameInformation> classNames = collectClassNames(dependency);
|
||||||
final String fileName = dependency.getFileName().toLowerCase();
|
final String fileName = dependency.getFileName().toLowerCase();
|
||||||
@@ -263,8 +279,8 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
final String msg = String.format("Unable to read JarFile '%s'.", dependency.getActualFilePath());
|
final String msg = String.format("Unable to read JarFile '%s'.", dependency.getActualFilePath());
|
||||||
//final AnalysisException ax = new AnalysisException(msg, ex);
|
//final AnalysisException ax = new AnalysisException(msg, ex);
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.WARNING, msg);
|
LOGGER.log(Level.WARNING, msg);
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
LOGGER.log(Level.FINE, "", ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
List<String> pomEntries;
|
List<String> pomEntries;
|
||||||
@@ -273,8 +289,8 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
final String msg = String.format("Unable to read Jar file entries in '%s'.", dependency.getActualFilePath());
|
final String msg = String.format("Unable to read Jar file entries in '%s'.", dependency.getActualFilePath());
|
||||||
//final AnalysisException ax = new AnalysisException(msg, ex);
|
//final AnalysisException ax = new AnalysisException(msg, ex);
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.WARNING, msg);
|
LOGGER.log(Level.WARNING, msg);
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINE, msg, ex);
|
LOGGER.log(Level.FINE, msg, ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (pomEntries.isEmpty()) {
|
if (pomEntries.isEmpty()) {
|
||||||
@@ -285,7 +301,7 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
try {
|
try {
|
||||||
pomProperties = retrievePomProperties(path, jar);
|
pomProperties = retrievePomProperties(path, jar);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINEST, "ignore this, failed reading a non-existent pom.properties", ex);
|
LOGGER.log(Level.FINEST, "ignore this, failed reading a non-existent pom.properties", ex);
|
||||||
}
|
}
|
||||||
Model pom = null;
|
Model pom = null;
|
||||||
try {
|
try {
|
||||||
@@ -314,8 +330,8 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
}
|
}
|
||||||
} catch (AnalysisException ex) {
|
} catch (AnalysisException ex) {
|
||||||
final String msg = String.format("An error occured while analyzing '%s'.", dependency.getActualFilePath());
|
final String msg = String.format("An error occured while analyzing '%s'.", dependency.getActualFilePath());
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.WARNING, msg);
|
LOGGER.log(Level.WARNING, msg);
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINE, "", ex);
|
LOGGER.log(Level.FINE, "", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return foundSomething;
|
return foundSomething;
|
||||||
@@ -392,7 +408,9 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
bos.flush();
|
bos.flush();
|
||||||
dependency.setActualFilePath(file.getAbsolutePath());
|
dependency.setActualFilePath(file.getAbsolutePath());
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.SEVERE, null, ex);
|
final String msg = String.format("An error occured reading '%s' from '%s'.", path, dependency.getFilePath());
|
||||||
|
LOGGER.warning(msg);
|
||||||
|
LOGGER.log(Level.SEVERE, "", ex);
|
||||||
} finally {
|
} finally {
|
||||||
closeStream(bos);
|
closeStream(bos);
|
||||||
closeStream(fos);
|
closeStream(fos);
|
||||||
@@ -408,18 +426,18 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
model = readPom(source);
|
model = readPom(source);
|
||||||
} catch (FileNotFoundException ex) {
|
} catch (FileNotFoundException ex) {
|
||||||
final String msg = String.format("Unable to parse pom '%s' in jar '%s' (File Not Found)", path, jar.getName());
|
final String msg = String.format("Unable to parse pom '%s' in jar '%s' (File Not Found)", path, jar.getName());
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.WARNING, msg);
|
LOGGER.log(Level.WARNING, msg);
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
LOGGER.log(Level.FINE, "", ex);
|
||||||
throw new AnalysisException(ex);
|
throw new AnalysisException(ex);
|
||||||
} catch (UnsupportedEncodingException ex) {
|
} catch (UnsupportedEncodingException ex) {
|
||||||
final String msg = String.format("Unable to parse pom '%s' in jar '%s' (IO Exception)", path, jar.getName());
|
final String msg = String.format("Unable to parse pom '%s' in jar '%s' (IO Exception)", path, jar.getName());
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.WARNING, msg);
|
LOGGER.log(Level.WARNING, msg);
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
LOGGER.log(Level.FINE, "", ex);
|
||||||
throw new AnalysisException(ex);
|
throw new AnalysisException(ex);
|
||||||
} catch (AnalysisException ex) {
|
} catch (AnalysisException ex) {
|
||||||
final String msg = String.format("Unable to parse pom '%s' in jar '%s'", path, jar.getName());
|
final String msg = String.format("Unable to parse pom '%s' in jar '%s'", path, jar.getName());
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.WARNING, msg);
|
LOGGER.log(Level.WARNING, msg);
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
LOGGER.log(Level.FINE, "", ex);
|
||||||
throw ex;
|
throw ex;
|
||||||
} finally {
|
} finally {
|
||||||
closeStream(fis);
|
closeStream(fis);
|
||||||
@@ -437,7 +455,7 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
try {
|
try {
|
||||||
stream.close();
|
stream.close();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINEST, null, ex);
|
LOGGER.log(Level.FINEST, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -452,7 +470,7 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
try {
|
try {
|
||||||
stream.close();
|
stream.close();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINEST, null, ex);
|
LOGGER.log(Level.FINEST, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -486,13 +504,13 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
throw new AnalysisException(ex);
|
throw new AnalysisException(ex);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
final String msg = String.format("Unable to parse pom '%s' in jar '%s' (IO Exception)", path, jar.getName());
|
final String msg = String.format("Unable to parse pom '%s' in jar '%s' (IO Exception)", path, jar.getName());
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.WARNING, msg);
|
LOGGER.log(Level.WARNING, msg);
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
LOGGER.log(Level.FINE, "", ex);
|
||||||
throw new AnalysisException(ex);
|
throw new AnalysisException(ex);
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
final String msg = String.format("Unexpected error during parsing of the pom '%s' in jar '%s'", path, jar.getName());
|
final String msg = String.format("Unexpected error during parsing of the pom '%s' in jar '%s'", path, jar.getName());
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.WARNING, msg);
|
LOGGER.log(Level.WARNING, msg);
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINE, null, ex);
|
LOGGER.log(Level.FINE, "", ex);
|
||||||
throw new AnalysisException(ex);
|
throw new AnalysisException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -899,12 +917,12 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
private File tempFileLocation = null;
|
private File tempFileLocation = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The initialize method does nothing for this Analyzer.
|
* Initializes the JarAnalyzer.
|
||||||
*
|
*
|
||||||
* @throws Exception is thrown if there is an exception creating a temporary directory
|
* @throws Exception is thrown if there is an exception creating a temporary directory
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void initialize() throws Exception {
|
public void initializeFileTypeAnalyzer() throws Exception {
|
||||||
final File baseDir = Settings.getTempDirectory();
|
final File baseDir = Settings.getTempDirectory();
|
||||||
if (!baseDir.exists()) {
|
if (!baseDir.exists()) {
|
||||||
if (!baseDir.mkdirs()) {
|
if (!baseDir.mkdirs()) {
|
||||||
@@ -929,10 +947,10 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
if (tempFileLocation != null && tempFileLocation.exists()) {
|
if (tempFileLocation != null && tempFileLocation.exists()) {
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINE, "Attempting to delete temporary files");
|
LOGGER.log(Level.FINE, "Attempting to delete temporary files");
|
||||||
final boolean success = FileUtils.delete(tempFileLocation);
|
final boolean success = FileUtils.delete(tempFileLocation);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.WARNING,
|
LOGGER.log(Level.WARNING,
|
||||||
"Failed to delete some temporary files, see the log for more details");
|
"Failed to delete some temporary files, see the log for more details");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1003,11 +1021,9 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
* @return true or false depending on if it is believed the entry is an "import" entry
|
* @return true or false depending on if it is believed the entry is an "import" entry
|
||||||
*/
|
*/
|
||||||
private boolean isImportPackage(String key, String value) {
|
private boolean isImportPackage(String key, String value) {
|
||||||
final Pattern packageRx = Pattern.compile("^((([a-zA-Z_#\\$0-9]\\.)+)\\s*\\;\\s*)+$");
|
final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$");
|
||||||
if (packageRx.matcher(value).matches()) {
|
final boolean matches = packageRx.matcher(value).matches();
|
||||||
return (key.contains("import") || key.contains("include"));
|
return matches && (key.contains("import") || key.contains("include") || value.length() > 10);
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1044,7 +1060,7 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
try {
|
try {
|
||||||
jar.close();
|
jar.close();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.FINEST, null, ex);
|
LOGGER.log(Level.FINEST, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import java.util.regex.Pattern;
|
|||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -36,7 +37,12 @@ import org.owasp.dependencycheck.dependency.Dependency;
|
|||||||
*
|
*
|
||||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||||
*/
|
*/
|
||||||
public class JavaScriptAnalyzer extends AbstractAnalyzer implements Analyzer {
|
public class JavaScriptAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(JavaScriptAnalyzer.class.getName());
|
||||||
|
|
||||||
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
|
//<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
|
||||||
/**
|
/**
|
||||||
@@ -72,17 +78,6 @@ public class JavaScriptAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
return ANALYZER_NAME;
|
return ANALYZER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this analyzer can process the given extension.
|
|
||||||
*
|
|
||||||
* @param extension the file extension to test for support.
|
|
||||||
* @return whether or not the specified file extension is supported by this analyzer.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return EXTENSIONS.contains(extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the phase that the analyzer is intended to run in.
|
* Returns the phase that the analyzer is intended to run in.
|
||||||
*
|
*
|
||||||
@@ -93,6 +88,15 @@ public class JavaScriptAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
return ANALYSIS_PHASE;
|
return ANALYSIS_PHASE;
|
||||||
}
|
}
|
||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
|
/**
|
||||||
|
* Returns the key used in the properties file to reference the analyzer's enabled property.
|
||||||
|
*
|
||||||
|
* @return the analyzer's enabled property setting key
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_JAVASCRIPT_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a specified JavaScript file and collects information from the copyright information contained within.
|
* Loads a specified JavaScript file and collects information from the copyright information contained within.
|
||||||
@@ -102,7 +106,7 @@ public class JavaScriptAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
* @throws AnalysisException is thrown if there is an error reading the JavaScript file.
|
* @throws AnalysisException is thrown if there is an error reading the JavaScript file.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
BufferedReader fin = null;;
|
BufferedReader fin = null;;
|
||||||
try {
|
try {
|
||||||
// /\*([^\*][^/]|[\r\n\f])+?\*/
|
// /\*([^\*][^/]|[\r\n\f])+?\*/
|
||||||
@@ -118,15 +122,20 @@ public class JavaScriptAnalyzer extends AbstractAnalyzer implements Analyzer {
|
|||||||
final String msg = String.format("Dependency file not found: '%s'", dependency.getActualFilePath());
|
final String msg = String.format("Dependency file not found: '%s'", dependency.getActualFilePath());
|
||||||
throw new AnalysisException(msg, ex);
|
throw new AnalysisException(msg, ex);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.getLogger(JavaScriptAnalyzer.class.getName()).log(Level.SEVERE, null, ex);
|
LOGGER.log(Level.SEVERE, null, ex);
|
||||||
} finally {
|
} finally {
|
||||||
if (fin != null) {
|
if (fin != null) {
|
||||||
try {
|
try {
|
||||||
fin.close();
|
fin.close();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.getLogger(JavaScriptAnalyzer.class.getName()).log(Level.FINEST, null, ex);
|
LOGGER.log(Level.FINEST, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initializeFileTypeAnalyzer() throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,20 +46,20 @@ import org.owasp.dependencycheck.utils.Settings;
|
|||||||
*
|
*
|
||||||
* @author colezlaw
|
* @author colezlaw
|
||||||
*/
|
*/
|
||||||
public class NexusAnalyzer extends AbstractAnalyzer {
|
public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The logger
|
* The logger.
|
||||||
*/
|
*/
|
||||||
private static final Logger LOGGER = Logger.getLogger(NexusAnalyzer.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(NexusAnalyzer.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the analyzer
|
* The name of the analyzer.
|
||||||
*/
|
*/
|
||||||
private static final String ANALYZER_NAME = "Nexus Analyzer";
|
private static final String ANALYZER_NAME = "Nexus Analyzer";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The phase in which the analyzer runs
|
* The phase in which the analyzer runs.
|
||||||
*/
|
*/
|
||||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
||||||
|
|
||||||
@@ -68,11 +68,6 @@ public class NexusAnalyzer extends AbstractAnalyzer {
|
|||||||
*/
|
*/
|
||||||
private static final Set<String> SUPPORTED_EXTENSIONS = newHashSet("jar");
|
private static final Set<String> SUPPORTED_EXTENSIONS = newHashSet("jar");
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether this is actually enabled. Will get set during initialization.
|
|
||||||
*/
|
|
||||||
private boolean enabled = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Nexus Search to be set up for this analyzer.
|
* The Nexus Search to be set up for this analyzer.
|
||||||
*/
|
*/
|
||||||
@@ -84,24 +79,23 @@ public class NexusAnalyzer extends AbstractAnalyzer {
|
|||||||
* @throws Exception if there's an error during initialization
|
* @throws Exception if there's an error during initialization
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void initialize() throws Exception {
|
public void initializeFileTypeAnalyzer() throws Exception {
|
||||||
enabled = Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED);
|
|
||||||
LOGGER.fine("Initializing Nexus Analyzer");
|
LOGGER.fine("Initializing Nexus Analyzer");
|
||||||
LOGGER.fine(String.format("Nexus Analyzer enabled: %s", enabled));
|
LOGGER.fine(String.format("Nexus Analyzer enabled: %s", isEnabled()));
|
||||||
if (enabled) {
|
if (isEnabled()) {
|
||||||
final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL);
|
final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL);
|
||||||
LOGGER.fine(String.format("Nexus Analyzer URL: %s", searchUrl));
|
LOGGER.fine(String.format("Nexus Analyzer URL: %s", searchUrl));
|
||||||
try {
|
try {
|
||||||
searcher = new NexusSearch(new URL(searchUrl));
|
searcher = new NexusSearch(new URL(searchUrl));
|
||||||
if (!searcher.preflightRequest()) {
|
if (!searcher.preflightRequest()) {
|
||||||
LOGGER.warning("There was an issue getting Nexus status. Disabling analyzer.");
|
LOGGER.warning("There was an issue getting Nexus status. Disabling analyzer.");
|
||||||
enabled = false;
|
setEnabled(false);
|
||||||
}
|
}
|
||||||
} catch (MalformedURLException mue) {
|
} catch (MalformedURLException mue) {
|
||||||
// I know that initialize can throw an exception, but we'll
|
// I know that initialize can throw an exception, but we'll
|
||||||
// just disable the analyzer if the URL isn't valid
|
// just disable the analyzer if the URL isn't valid
|
||||||
LOGGER.warning(String.format("Property %s not a valid URL. Nexus Analyzer disabled", searchUrl));
|
LOGGER.warning(String.format("Property %s not a valid URL. Nexus Analyzer disabled", searchUrl));
|
||||||
enabled = false;
|
setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,6 +110,16 @@ public class NexusAnalyzer extends AbstractAnalyzer {
|
|||||||
return ANALYZER_NAME;
|
return ANALYZER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the key used in the properties file to reference the analyzer's enabled property.
|
||||||
|
*
|
||||||
|
* @return the analyzer's enabled property setting key
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_NEXUS_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the analysis phase under which the analyzer runs.
|
* Returns the analysis phase under which the analyzer runs.
|
||||||
*
|
*
|
||||||
@@ -136,17 +140,6 @@ public class NexusAnalyzer extends AbstractAnalyzer {
|
|||||||
return SUPPORTED_EXTENSIONS;
|
return SUPPORTED_EXTENSIONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the incoming extension is supported.
|
|
||||||
*
|
|
||||||
* @param extension the extension to check for support
|
|
||||||
* @return whether the extension is supported
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return SUPPORTED_EXTENSIONS.contains(extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the analysis.
|
* Performs the analysis.
|
||||||
*
|
*
|
||||||
@@ -155,12 +148,7 @@ public class NexusAnalyzer extends AbstractAnalyzer {
|
|||||||
* @throws AnalysisException when there's an exception during analysis
|
* @throws AnalysisException when there's an exception during analysis
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
// Make a quick exit if this analyzer is disabled
|
|
||||||
if (!enabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final MavenArtifact ma = searcher.searchSha1(dependency.getSha1sum());
|
final MavenArtifact ma = searcher.searchSha1(dependency.getSha1sum());
|
||||||
if (ma.getGroupId() != null && !"".equals(ma.getGroupId())) {
|
if (ma.getGroupId() != null && !"".equals(ma.getGroupId())) {
|
||||||
@@ -188,5 +176,3 @@ public class NexusAnalyzer extends AbstractAnalyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// vim: cc=120:sw=4:ts=4:sts=4
|
|
||||||
|
|||||||
@@ -18,36 +18,40 @@
|
|||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
import org.owasp.dependencycheck.data.nuget.NugetPackage;
|
import org.owasp.dependencycheck.data.nuget.NugetPackage;
|
||||||
|
import org.owasp.dependencycheck.data.nuget.NuspecParseException;
|
||||||
import org.owasp.dependencycheck.data.nuget.NuspecParser;
|
import org.owasp.dependencycheck.data.nuget.NuspecParser;
|
||||||
import org.owasp.dependencycheck.data.nuget.XPathNuspecParser;
|
import org.owasp.dependencycheck.data.nuget.XPathNuspecParser;
|
||||||
import org.owasp.dependencycheck.dependency.Confidence;
|
import org.owasp.dependencycheck.dependency.Confidence;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Analyzer which will parse a Nuspec file to gather module information.
|
* Analyzer which will parse a Nuspec file to gather module information.
|
||||||
*
|
*
|
||||||
* @author colezlaw
|
* @author colezlaw
|
||||||
*/
|
*/
|
||||||
public class NuspecAnalyzer extends AbstractAnalyzer {
|
public class NuspecAnalyzer extends AbstractFileTypeAnalyzer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The logger
|
* The logger.
|
||||||
*/
|
*/
|
||||||
private static final Logger LOGGER = Logger.getLogger(NuspecAnalyzer.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(NuspecAnalyzer.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the analyzer
|
* The name of the analyzer.
|
||||||
*/
|
*/
|
||||||
private static final String ANALYZER_NAME = "Nuspec Analyzer";
|
private static final String ANALYZER_NAME = "Nuspec Analyzer";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The phase in which the analyzer runs
|
* The phase in which the analyzer runs.
|
||||||
*/
|
*/
|
||||||
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
|
||||||
|
|
||||||
@@ -62,7 +66,7 @@ public class NuspecAnalyzer extends AbstractAnalyzer {
|
|||||||
* @throws Exception if there's an error during initialization
|
* @throws Exception if there's an error during initialization
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void initialize() throws Exception {
|
public void initializeFileTypeAnalyzer() throws Exception {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,6 +79,16 @@ public class NuspecAnalyzer extends AbstractAnalyzer {
|
|||||||
return ANALYZER_NAME;
|
return ANALYZER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the key used in the properties file to reference the analyzer's enabled property.
|
||||||
|
*
|
||||||
|
* @return the analyzer's enabled property setting key
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAnalyzerEnabledSettingKey() {
|
||||||
|
return Settings.KEYS.ANALYZER_NUSPEC_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the analysis phase under which the analyzer runs.
|
* Returns the analysis phase under which the analyzer runs.
|
||||||
*
|
*
|
||||||
@@ -95,17 +109,6 @@ public class NuspecAnalyzer extends AbstractAnalyzer {
|
|||||||
return SUPPORTED_EXTENSIONS;
|
return SUPPORTED_EXTENSIONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the incoming extension is supported.
|
|
||||||
*
|
|
||||||
* @param extension the extension to check for support
|
|
||||||
* @return whether the extension is supported
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return SUPPORTED_EXTENSIONS.contains(extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the analysis.
|
* Performs the analysis.
|
||||||
*
|
*
|
||||||
@@ -114,8 +117,8 @@ public class NuspecAnalyzer extends AbstractAnalyzer {
|
|||||||
* @throws AnalysisException when there's an exception during analysis
|
* @throws AnalysisException when there's an exception during analysis
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
LOGGER.log(Level.INFO, "Checking Nuspec file {0}", dependency.toString());
|
LOGGER.log(Level.FINE, "Checking Nuspec file {0}", dependency.toString());
|
||||||
try {
|
try {
|
||||||
final NuspecParser parser = new XPathNuspecParser();
|
final NuspecParser parser = new XPathNuspecParser();
|
||||||
NugetPackage np = null;
|
NugetPackage np = null;
|
||||||
@@ -123,11 +126,15 @@ public class NuspecAnalyzer extends AbstractAnalyzer {
|
|||||||
try {
|
try {
|
||||||
fis = new FileInputStream(dependency.getActualFilePath());
|
fis = new FileInputStream(dependency.getActualFilePath());
|
||||||
np = parser.parse(fis);
|
np = parser.parse(fis);
|
||||||
|
} catch (NuspecParseException ex) {
|
||||||
|
throw new AnalysisException(ex);
|
||||||
|
} catch (FileNotFoundException ex) {
|
||||||
|
throw new AnalysisException(ex);
|
||||||
} finally {
|
} finally {
|
||||||
if (fis != null) {
|
if (fis != null) {
|
||||||
try {
|
try {
|
||||||
fis.close();
|
fis.close();
|
||||||
} catch (Throwable e) {
|
} catch (IOException e) {
|
||||||
LOGGER.fine("Error closing input stream");
|
LOGGER.fine("Error closing input stream");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,5 +154,3 @@ public class NuspecAnalyzer extends AbstractAnalyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// vim: cc=120:sw=4:ts=4:sts=4
|
|
||||||
|
|||||||
@@ -17,12 +17,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
@@ -62,6 +61,7 @@ public class NvdCveAnalyzer implements Analyzer {
|
|||||||
/**
|
/**
|
||||||
* Closes the data source.
|
* Closes the data source.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
cveDB.close();
|
cveDB.close();
|
||||||
cveDB = null;
|
cveDB = null;
|
||||||
@@ -96,6 +96,7 @@ public class NvdCveAnalyzer implements Analyzer {
|
|||||||
* @param engine The analysis engine
|
* @param engine The analysis engine
|
||||||
* @throws AnalysisException is thrown if there is an issue analyzing the dependency
|
* @throws AnalysisException is thrown if there is an issue analyzing the dependency
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
for (Identifier id : dependency.getIdentifiers()) {
|
for (Identifier id : dependency.getIdentifiers()) {
|
||||||
if ("cpe".equals(id.getType())) {
|
if ("cpe".equals(id.getType())) {
|
||||||
@@ -110,48 +111,32 @@ public class NvdCveAnalyzer implements Analyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true because this analyzer supports all dependency types.
|
|
||||||
*
|
|
||||||
* @return true.
|
|
||||||
*/
|
|
||||||
public Set<String> getSupportedExtensions() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of this analyzer.
|
* Returns the name of this analyzer.
|
||||||
*
|
*
|
||||||
* @return the name of this analyzer.
|
* @return the name of this analyzer.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "NVD CVE Analyzer";
|
return "NVD CVE Analyzer";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true because this analyzer supports all dependency types.
|
|
||||||
*
|
|
||||||
* @param extension the file extension of the dependency being analyzed.
|
|
||||||
* @return true.
|
|
||||||
*/
|
|
||||||
public boolean supportsExtension(String extension) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the analysis phase that this analyzer should run in.
|
* Returns the analysis phase that this analyzer should run in.
|
||||||
*
|
*
|
||||||
* @return the analysis phase that this analyzer should run in.
|
* @return the analysis phase that this analyzer should run in.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public AnalysisPhase getAnalysisPhase() {
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
return AnalysisPhase.FINDING_ANALYSIS;
|
return AnalysisPhase.FINDING_ANALYSIS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the NVD CVE Lucene Index.
|
* Opens the database used to gather NVD CVE data.
|
||||||
*
|
*
|
||||||
* @throws Exception is thrown if there is an issue opening the index.
|
* @throws Exception is thrown if there is an issue opening the index.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void initialize() throws Exception {
|
public void initialize() throws Exception {
|
||||||
this.open();
|
this.open();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
|||||||
import org.owasp.dependencycheck.data.update.NvdCveInfo;
|
import org.owasp.dependencycheck.data.update.NvdCveInfo;
|
||||||
import org.owasp.dependencycheck.utils.DownloadFailedException;
|
import org.owasp.dependencycheck.utils.DownloadFailedException;
|
||||||
import org.owasp.dependencycheck.utils.Downloader;
|
import org.owasp.dependencycheck.utils.Downloader;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A callable object to download two files.
|
* A callable object to download two files.
|
||||||
@@ -53,8 +54,8 @@ public class CallableDownloadTask implements Callable<Future<ProcessTask>> {
|
|||||||
final File file2;
|
final File file2;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
file1 = File.createTempFile("cve" + nvdCveInfo.getId() + "_", ".xml");
|
file1 = File.createTempFile("cve" + nvdCveInfo.getId() + "_", ".xml", Settings.getTempDirectory());
|
||||||
file2 = File.createTempFile("cve_1_2_" + nvdCveInfo.getId() + "_", ".xml");
|
file2 = File.createTempFile("cve_1_2_" + nvdCveInfo.getId() + "_", ".xml", Settings.getTempDirectory());
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,16 +106,26 @@ public class Dependency implements Comparable<Dependency> {
|
|||||||
/**
|
/**
|
||||||
* Returns the file name of the dependency.
|
* Returns the file name of the dependency.
|
||||||
*
|
*
|
||||||
* @return the file name of the dependency.
|
* @return the file name of the dependency
|
||||||
*/
|
*/
|
||||||
public String getFileName() {
|
public String getFileName() {
|
||||||
return this.fileName;
|
return this.fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the file name of the dependency with the backslash escaped for use in JavaScript. This is a complete hack
|
||||||
|
* as I could not get the replace to work in the template itself.
|
||||||
|
*
|
||||||
|
* @return the file name of the dependency with the backslash escaped for use in JavaScript
|
||||||
|
*/
|
||||||
|
public String getFileNameForJavaScript() {
|
||||||
|
return this.fileName.replace("\\", "\\\\");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the file name of the dependency.
|
* Sets the file name of the dependency.
|
||||||
*
|
*
|
||||||
* @param fileName the file name of the dependency.
|
* @param fileName the file name of the dependency
|
||||||
*/
|
*/
|
||||||
public void setFileName(String fileName) {
|
public void setFileName(String fileName) {
|
||||||
this.fileName = fileName;
|
this.fileName = fileName;
|
||||||
@@ -124,7 +134,7 @@ public class Dependency implements Comparable<Dependency> {
|
|||||||
/**
|
/**
|
||||||
* Sets the actual file path of the dependency on disk.
|
* Sets the actual file path of the dependency on disk.
|
||||||
*
|
*
|
||||||
* @param actualFilePath the file path of the dependency.
|
* @param actualFilePath the file path of the dependency
|
||||||
*/
|
*/
|
||||||
public void setActualFilePath(String actualFilePath) {
|
public void setActualFilePath(String actualFilePath) {
|
||||||
this.actualFilePath = actualFilePath;
|
this.actualFilePath = actualFilePath;
|
||||||
@@ -137,7 +147,7 @@ public class Dependency implements Comparable<Dependency> {
|
|||||||
/**
|
/**
|
||||||
* Gets the file path of the dependency.
|
* Gets the file path of the dependency.
|
||||||
*
|
*
|
||||||
* @return the file path of the dependency.
|
* @return the file path of the dependency
|
||||||
*/
|
*/
|
||||||
public String getActualFilePath() {
|
public String getActualFilePath() {
|
||||||
return this.actualFilePath;
|
return this.actualFilePath;
|
||||||
@@ -146,7 +156,7 @@ public class Dependency implements Comparable<Dependency> {
|
|||||||
/**
|
/**
|
||||||
* Gets a reference to the File object.
|
* Gets a reference to the File object.
|
||||||
*
|
*
|
||||||
* @return the File object.
|
* @return the File object
|
||||||
*/
|
*/
|
||||||
public File getActualFile() {
|
public File getActualFile() {
|
||||||
return new File(this.actualFilePath);
|
return new File(this.actualFilePath);
|
||||||
@@ -155,7 +165,7 @@ public class Dependency implements Comparable<Dependency> {
|
|||||||
/**
|
/**
|
||||||
* Sets the file path of the dependency.
|
* Sets the file path of the dependency.
|
||||||
*
|
*
|
||||||
* @param filePath the file path of the dependency.
|
* @param filePath the file path of the dependency
|
||||||
*/
|
*/
|
||||||
public void setFilePath(String filePath) {
|
public void setFilePath(String filePath) {
|
||||||
this.filePath = filePath;
|
this.filePath = filePath;
|
||||||
@@ -168,7 +178,7 @@ public class Dependency implements Comparable<Dependency> {
|
|||||||
* <b>NOTE:</b> This may not be the actual path of the file on disk. The actual path of the file on disk can be
|
* <b>NOTE:</b> This may not be the actual path of the file on disk. The actual path of the file on disk can be
|
||||||
* obtained via the getActualFilePath().</p>
|
* obtained via the getActualFilePath().</p>
|
||||||
*
|
*
|
||||||
* @return the file path of the dependency.
|
* @return the file path of the dependency
|
||||||
*/
|
*/
|
||||||
public String getFilePath() {
|
public String getFilePath() {
|
||||||
return this.filePath;
|
return this.filePath;
|
||||||
@@ -177,7 +187,7 @@ public class Dependency implements Comparable<Dependency> {
|
|||||||
/**
|
/**
|
||||||
* Sets the file name of the dependency.
|
* Sets the file name of the dependency.
|
||||||
*
|
*
|
||||||
* @param fileExtension the file name of the dependency.
|
* @param fileExtension the file name of the dependency
|
||||||
*/
|
*/
|
||||||
public void setFileExtension(String fileExtension) {
|
public void setFileExtension(String fileExtension) {
|
||||||
this.fileExtension = fileExtension;
|
this.fileExtension = fileExtension;
|
||||||
@@ -186,7 +196,7 @@ public class Dependency implements Comparable<Dependency> {
|
|||||||
/**
|
/**
|
||||||
* Gets the file extension of the dependency.
|
* Gets the file extension of the dependency.
|
||||||
*
|
*
|
||||||
* @return the file extension of the dependency.
|
* @return the file extension of the dependency
|
||||||
*/
|
*/
|
||||||
public String getFileExtension() {
|
public String getFileExtension() {
|
||||||
return this.fileExtension;
|
return this.fileExtension;
|
||||||
@@ -231,7 +241,7 @@ public class Dependency implements Comparable<Dependency> {
|
|||||||
/**
|
/**
|
||||||
* Returns a List of Identifiers.
|
* Returns a List of Identifiers.
|
||||||
*
|
*
|
||||||
* @return an ArrayList of Identifiers.
|
* @return an ArrayList of Identifiers
|
||||||
*/
|
*/
|
||||||
public Set<Identifier> getIdentifiers() {
|
public Set<Identifier> getIdentifiers() {
|
||||||
return this.identifiers;
|
return this.identifiers;
|
||||||
@@ -240,7 +250,7 @@ public class Dependency implements Comparable<Dependency> {
|
|||||||
/**
|
/**
|
||||||
* Sets a List of Identifiers.
|
* Sets a List of Identifiers.
|
||||||
*
|
*
|
||||||
* @param identifiers A list of Identifiers.
|
* @param identifiers A list of Identifiers
|
||||||
*/
|
*/
|
||||||
public void setIdentifiers(Set<Identifier> identifiers) {
|
public void setIdentifiers(Set<Identifier> identifiers) {
|
||||||
this.identifiers = identifiers;
|
this.identifiers = identifiers;
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* 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) 2014 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.exception;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An exception used when using @{link DependencyCheckScanAgent} to conduct a scan and the scan fails.
|
||||||
|
*
|
||||||
|
* @author Steve Springett <steve.springett@owasp.org>
|
||||||
|
*/
|
||||||
|
public class ScanAgentException extends IOException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The serial version uid.
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new ScanAgentException.
|
||||||
|
*/
|
||||||
|
public ScanAgentException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new ScanAgentException.
|
||||||
|
*
|
||||||
|
* @param msg a message for the exception.
|
||||||
|
*/
|
||||||
|
public ScanAgentException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new NoDataException.
|
||||||
|
*
|
||||||
|
* @param ex the cause of the exception.
|
||||||
|
*/
|
||||||
|
public ScanAgentException(Throwable ex) {
|
||||||
|
super(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new ScanAgentException.
|
||||||
|
*
|
||||||
|
* @param msg a message for the exception.
|
||||||
|
* @param ex the cause of the exception.
|
||||||
|
*/
|
||||||
|
public ScanAgentException(String msg, Throwable ex) {
|
||||||
|
super(msg, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -140,13 +140,13 @@ public class ReportGenerator {
|
|||||||
*/
|
*/
|
||||||
public void generateReports(String outputDir, Format format) throws IOException, Exception {
|
public void generateReports(String outputDir, Format format) throws IOException, Exception {
|
||||||
if (format == Format.XML || format == Format.ALL) {
|
if (format == Format.XML || format == Format.ALL) {
|
||||||
generateReport("XmlReport", outputDir + File.separator + "DependencyCheck-Report.xml");
|
generateReport("XmlReport", outputDir + File.separator + "dependency-check-report.xml");
|
||||||
}
|
}
|
||||||
if (format == Format.HTML || format == Format.ALL) {
|
if (format == Format.HTML || format == Format.ALL) {
|
||||||
generateReport("HtmlReport", outputDir + File.separator + "DependencyCheck-Report.html");
|
generateReport("HtmlReport", outputDir + File.separator + "dependency-check-report.html");
|
||||||
}
|
}
|
||||||
if (format == Format.VULN || format == Format.ALL) {
|
if (format == Format.VULN || format == Format.ALL) {
|
||||||
generateReport("VulnerabilityReport", outputDir + File.separator + "DependencyCheck-Vulnerability.html");
|
generateReport("VulnerabilityReport", outputDir + File.separator + "dependency-check-vulnerability.html");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,68 +46,101 @@ public final class Downloader {
|
|||||||
/**
|
/**
|
||||||
* Retrieves a file from a given URL and saves it to the outputPath.
|
* Retrieves a file from a given URL and saves it to the outputPath.
|
||||||
*
|
*
|
||||||
* @param url the URL of the file to download.
|
* @param url the URL of the file to download
|
||||||
* @param outputPath the path to the save the file to.
|
* @param outputPath the path to the save the file to
|
||||||
* @throws DownloadFailedException is thrown if there is an error downloading the file.
|
* @throws DownloadFailedException is thrown if there is an error downloading the file
|
||||||
*/
|
*/
|
||||||
public static void fetchFile(URL url, File outputPath) throws DownloadFailedException {
|
public static void fetchFile(URL url, File outputPath) throws DownloadFailedException {
|
||||||
HttpURLConnection conn = null;
|
fetchFile(url, outputPath, true);
|
||||||
try {
|
}
|
||||||
conn = URLConnectionFactory.createHttpURLConnection(url);
|
|
||||||
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
|
|
||||||
conn.connect();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
try {
|
|
||||||
if (conn != null) {
|
|
||||||
conn.disconnect();
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
conn = null;
|
|
||||||
}
|
|
||||||
throw new DownloadFailedException("Error downloading file.", ex);
|
|
||||||
}
|
|
||||||
final String encoding = conn.getContentEncoding();
|
|
||||||
|
|
||||||
BufferedOutputStream writer = null;
|
/**
|
||||||
InputStream reader = null;
|
* Retrieves a file from a given URL and saves it to the outputPath.
|
||||||
try {
|
*
|
||||||
if (encoding != null && "gzip".equalsIgnoreCase(encoding)) {
|
* @param url the URL of the file to download
|
||||||
reader = new GZIPInputStream(conn.getInputStream());
|
* @param outputPath the path to the save the file to
|
||||||
} else if (encoding != null && "deflate".equalsIgnoreCase(encoding)) {
|
* @param useProxy whether to use the configured proxy when downloading files
|
||||||
reader = new InflaterInputStream(conn.getInputStream());
|
* @throws DownloadFailedException is thrown if there is an error downloading the file
|
||||||
|
*/
|
||||||
|
public static void fetchFile(URL url, File outputPath, boolean useProxy) throws DownloadFailedException {
|
||||||
|
if ("file".equalsIgnoreCase(url.getProtocol())) {
|
||||||
|
File file;
|
||||||
|
try {
|
||||||
|
file = new File(url.toURI());
|
||||||
|
} catch (URISyntaxException ex) {
|
||||||
|
final String msg = String.format("Download failed, unable to locate '%s'", url.toString());
|
||||||
|
throw new DownloadFailedException(msg);
|
||||||
|
}
|
||||||
|
if (file.exists()) {
|
||||||
|
try {
|
||||||
|
org.apache.commons.io.FileUtils.copyFile(file, outputPath);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
final String msg = String.format("Download failed, unable to copy '%s'", url.toString());
|
||||||
|
throw new DownloadFailedException(msg);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
reader = conn.getInputStream();
|
final String msg = String.format("Download failed, file does not exist '%s'", url.toString());
|
||||||
}
|
throw new DownloadFailedException(msg);
|
||||||
|
|
||||||
writer = new BufferedOutputStream(new FileOutputStream(outputPath));
|
|
||||||
final byte[] buffer = new byte[4096];
|
|
||||||
int bytesRead;
|
|
||||||
while ((bytesRead = reader.read(buffer)) > 0) {
|
|
||||||
writer.write(buffer, 0, bytesRead);
|
|
||||||
}
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
throw new DownloadFailedException("Error saving downloaded file.", ex);
|
|
||||||
} finally {
|
|
||||||
if (writer != null) {
|
|
||||||
try {
|
|
||||||
writer.close();
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
Logger.getLogger(Downloader.class.getName()).log(Level.FINEST,
|
|
||||||
"Error closing the writer in Downloader.", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (reader != null) {
|
|
||||||
try {
|
|
||||||
reader.close();
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
Logger.getLogger(Downloader.class.getName()).log(Level.FINEST,
|
|
||||||
"Error closing the reader in Downloader.", ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
HttpURLConnection conn = null;
|
||||||
try {
|
try {
|
||||||
conn.disconnect();
|
conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
|
||||||
|
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
|
||||||
|
conn.connect();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
try {
|
||||||
|
if (conn != null) {
|
||||||
|
conn.disconnect();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
conn = null;
|
||||||
|
}
|
||||||
|
throw new DownloadFailedException("Error downloading file.", ex);
|
||||||
|
}
|
||||||
|
final String encoding = conn.getContentEncoding();
|
||||||
|
|
||||||
|
BufferedOutputStream writer = null;
|
||||||
|
InputStream reader = null;
|
||||||
|
try {
|
||||||
|
if (encoding != null && "gzip".equalsIgnoreCase(encoding)) {
|
||||||
|
reader = new GZIPInputStream(conn.getInputStream());
|
||||||
|
} else if (encoding != null && "deflate".equalsIgnoreCase(encoding)) {
|
||||||
|
reader = new InflaterInputStream(conn.getInputStream());
|
||||||
|
} else {
|
||||||
|
reader = conn.getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
writer = new BufferedOutputStream(new FileOutputStream(outputPath));
|
||||||
|
final byte[] buffer = new byte[4096];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = reader.read(buffer)) > 0) {
|
||||||
|
writer.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
throw new DownloadFailedException("Error saving downloaded file.", ex);
|
||||||
} finally {
|
} finally {
|
||||||
conn = null;
|
if (writer != null) {
|
||||||
|
try {
|
||||||
|
writer.close();
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
Logger.getLogger(Downloader.class.getName()).log(Level.FINEST,
|
||||||
|
"Error closing the writer in Downloader.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reader != null) {
|
||||||
|
try {
|
||||||
|
reader.close();
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
Logger.getLogger(Downloader.class.getName()).log(Level.FINEST,
|
||||||
|
"Error closing the reader in Downloader.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
conn.disconnect();
|
||||||
|
} finally {
|
||||||
|
conn = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,20 +155,11 @@ public final class Downloader {
|
|||||||
*/
|
*/
|
||||||
public static long getLastModified(URL url) throws DownloadFailedException {
|
public static long getLastModified(URL url) throws DownloadFailedException {
|
||||||
long timestamp = 0;
|
long timestamp = 0;
|
||||||
//TODO add the FPR protocol?
|
//TODO add the FTP protocol?
|
||||||
if ("file".equalsIgnoreCase(url.getProtocol())) {
|
if ("file".equalsIgnoreCase(url.getProtocol())) {
|
||||||
File lastModifiedFile;
|
File lastModifiedFile;
|
||||||
try {
|
try {
|
||||||
// if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
|
|
||||||
// String filePath = url.toString();
|
|
||||||
// if (filePath.matches("file://[a-zA-Z]:.*")) {
|
|
||||||
// f = new File(filePath.substring(7));
|
|
||||||
// } else {
|
|
||||||
// f = new File(url.toURI());
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
lastModifiedFile = new File(url.toURI());
|
lastModifiedFile = new File(url.toURI());
|
||||||
// }
|
|
||||||
} catch (URISyntaxException ex) {
|
} 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'; is the cve.url-2.0.modified property set correctly?", url.toString());
|
||||||
throw new DownloadFailedException(msg);
|
throw new DownloadFailedException(msg);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
@@ -39,6 +40,16 @@ import org.owasp.dependencycheck.Engine;
|
|||||||
*/
|
*/
|
||||||
public final class FileUtils {
|
public final class FileUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bit bucket for non-Windows systems
|
||||||
|
*/
|
||||||
|
private static final String BIT_BUCKET_UNIX = "/dev/null";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bit bucket for Windows systems (yes, only one 'L')
|
||||||
|
*/
|
||||||
|
private static final String BIT_BUCKET_WIN = "NUL";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The buffer size to use when extracting files from the archive.
|
* The buffer size to use when extracting files from the archive.
|
||||||
*/
|
*/
|
||||||
@@ -73,19 +84,38 @@ public final class FileUtils {
|
|||||||
*/
|
*/
|
||||||
public static boolean delete(File file) {
|
public static boolean delete(File file) {
|
||||||
boolean success = true;
|
boolean success = true;
|
||||||
if (file.isDirectory()) { //some of this may duplicative of deleteQuietly....
|
|
||||||
for (File f : file.listFiles()) {
|
|
||||||
success &= delete(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!org.apache.commons.io.FileUtils.deleteQuietly(file)) {
|
if (!org.apache.commons.io.FileUtils.deleteQuietly(file)) {
|
||||||
success = false;
|
success = false;
|
||||||
final String msg = String.format("Failed to delete file: %s", file.getPath());
|
final String msg = String.format("Failed to delete file: %s; attempting to delete on exit.", file.getPath());
|
||||||
Logger.getLogger(FileUtils.class.getName()).log(Level.FINE, msg);
|
Logger.getLogger(FileUtils.class.getName()).log(Level.FINE, msg);
|
||||||
|
file.deleteOnExit();
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a new temporary file name that is guaranteed to be unique.
|
||||||
|
*
|
||||||
|
* @param prefix the prefix for the file name to generate
|
||||||
|
* @param extension the extension of the generated file name
|
||||||
|
* @return a temporary File
|
||||||
|
* @throws java.io.IOException thrown if the temporary folder could not be created
|
||||||
|
*/
|
||||||
|
public static File getTempFile(String prefix, String extension) throws IOException {
|
||||||
|
final File dir = Settings.getTempDirectory();
|
||||||
|
if (!dir.exists()) {
|
||||||
|
if (!dir.mkdirs()) {
|
||||||
|
throw new IOException("Unable to create temporary folder");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final String tempFileName = String.format("%s%s.%s", prefix, UUID.randomUUID().toString(), extension);
|
||||||
|
final File tempFile = new File(dir, tempFileName);
|
||||||
|
if (tempFile.exists()) {
|
||||||
|
return getTempFile(prefix, extension);
|
||||||
|
}
|
||||||
|
return tempFile;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the data directory. If a path was specified in dependencycheck.properties or was specified using the
|
* Returns the data directory. If a path was specified in dependencycheck.properties or was specified using the
|
||||||
* Settings object, and the path exists, that path will be returned as a File object. If it does not exist, then a
|
* Settings object, and the path exists, that path will be returned as a File object. If it does not exist, then a
|
||||||
@@ -218,4 +248,17 @@ public final class FileUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the bit bucket for the OS. '/dev/null' for Unix and 'NUL' for Windows
|
||||||
|
*
|
||||||
|
* @return a String containing the bit bucket
|
||||||
|
*/
|
||||||
|
public static String getBitBucket() {
|
||||||
|
if (System.getProperty("os.name").startsWith("Windows")) {
|
||||||
|
return BIT_BUCKET_WIN;
|
||||||
|
} else {
|
||||||
|
return BIT_BUCKET_UNIX;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,6 +145,26 @@ public final class Settings {
|
|||||||
* The key for a list of suppression files.
|
* The key for a list of suppression files.
|
||||||
*/
|
*/
|
||||||
public static final String SUPPRESSION_FILE = "suppression.file";
|
public static final String SUPPRESSION_FILE = "suppression.file";
|
||||||
|
/**
|
||||||
|
* The properties key for whether the Jar Analyzer is enabled.
|
||||||
|
*/
|
||||||
|
public static final String ANALYZER_JAR_ENABLED = "analyzer.jar.enabled";
|
||||||
|
/**
|
||||||
|
* The properties key for whether the Archive analyzer is enabled.
|
||||||
|
*/
|
||||||
|
public static final String ANALYZER_ARCHIVE_ENABLED = "analyzer.archive.enabled";
|
||||||
|
/**
|
||||||
|
* The properties key for whether the .NET Assembly analyzer is enabled.
|
||||||
|
*/
|
||||||
|
public static final String ANALYZER_ASSEMBLY_ENABLED = "analyzer.assembly.enabled";
|
||||||
|
/**
|
||||||
|
* The properties key for whether the .NET Nuspec analyzer is enabled.
|
||||||
|
*/
|
||||||
|
public static final String ANALYZER_NUSPEC_ENABLED = "analyzer.nuspec.enabled";
|
||||||
|
/**
|
||||||
|
* The properties key for whether the JavaScript analyzer is enabled.
|
||||||
|
*/
|
||||||
|
public static final String ANALYZER_JAVASCRIPT_ENABLED = "analyzer.javascript.enabled";
|
||||||
/**
|
/**
|
||||||
* The properties key for whether the Nexus analyzer is enabled.
|
* The properties key for whether the Nexus analyzer is enabled.
|
||||||
*/
|
*/
|
||||||
@@ -511,4 +531,28 @@ public final class Settings {
|
|||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a boolean value from the properties file. If the value was specified as a system property or passed in
|
||||||
|
* via the <code>-Dprop=value</code> argument this method will return the value from the system properties before
|
||||||
|
* the values in the contained configuration file.
|
||||||
|
*
|
||||||
|
* @param key the key to lookup within the properties file
|
||||||
|
* @param defaultValue the default value to return if the setting does not exist
|
||||||
|
* @return the property from the properties file
|
||||||
|
* @throws InvalidSettingException is thrown if there is an error retrieving the setting
|
||||||
|
*/
|
||||||
|
public static boolean getBoolean(String key, boolean defaultValue) throws InvalidSettingException {
|
||||||
|
boolean value;
|
||||||
|
try {
|
||||||
|
final String strValue = Settings.getString(key);
|
||||||
|
if (strValue == null) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
value = Boolean.parseBoolean(strValue);
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
throw new InvalidSettingException("Could not convert property '" + key + "' to an int.", ex);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -42,9 +42,15 @@ cve.startyear=2002
|
|||||||
cve.url-2.0.base=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
|
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
|
cve.url-1.2.base=http://nvd.nist.gov/download/nvdcve-%d.xml
|
||||||
|
|
||||||
|
# file type analyzer settings:
|
||||||
|
analyzer.archive.enabled=true
|
||||||
|
analyzer.jar.enabled=true
|
||||||
|
analyzer.nuspec.enabled=true
|
||||||
|
analyzer.assembly.enabled=true
|
||||||
|
|
||||||
# the URL for searching Nexus for SHA-1 hashes and whether it's enabled
|
# the URL for searching Nexus for SHA-1 hashes and whether it's enabled
|
||||||
analyzer.nexus.enabled=true
|
analyzer.nexus.enabled=true
|
||||||
analyzer.nexus.url=http://repository.sonatype.org/service/local/
|
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)
|
# If set to true, the proxy will still ONLY be used if the proxy properties (proxy.url, proxy.port)
|
||||||
# are configured
|
# are configured
|
||||||
analyzer.nexus.proxy=true
|
analyzer.nexus.proxy=true
|
||||||
|
|||||||
@@ -448,6 +448,11 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|||||||
color: blue;
|
color: blue;
|
||||||
float:right;
|
float:right;
|
||||||
}
|
}
|
||||||
|
.disclaimer {
|
||||||
|
color: #888888;
|
||||||
|
font: 9px "Droid Sans",Arial,"Helvetica Neue","Lucida Grande",sans-serif
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -459,6 +464,12 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|||||||
</div>
|
</div>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<h1>Dependency-Check Report</h1>
|
<h1>Dependency-Check Report</h1>
|
||||||
|
<p class="disclaimer">Dependency-Check is an open source tool performing a best effort analysis of 3rd party dependencies;
|
||||||
|
false positives and false negatives may exist in the analysis performed by the tool. Use of the tool and
|
||||||
|
the reporting provided constitutes acceptance for use in an AS IS condition, and there are NO warranties,
|
||||||
|
implied or otherwise, with regard to the analysis or its use. Any use of the tool and the reporting provided
|
||||||
|
is at the user’s risk. In no event shall the copyright holder or OWASP be held liable for any damages whatsoever
|
||||||
|
arising out of or in connection with the use of this tool, the analysis performed, or the resulting report.</p>
|
||||||
]]#
|
]]#
|
||||||
<h2 class="">Project: $esc.html($applicationName)</h2>
|
<h2 class="">Project: $esc.html($applicationName)</h2>
|
||||||
<div class="">
|
<div class="">
|
||||||
@@ -586,7 +597,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|||||||
#end
|
#end
|
||||||
#if ($id.type=="cpe")
|
#if ($id.type=="cpe")
|
||||||
##yes, we are HTML Encoding into JavaScript... the escape utils don't have a JS Encode and I haven't written one yet
|
##yes, we are HTML Encoding into JavaScript... the escape utils don't have a JS Encode and I haven't written one yet
|
||||||
<button class="copybutton" onclick="copyText('$esc.html($dependency.FileName)', '$esc.html($dependency.Sha1sum)', 'cpe', '$esc.html($id.value)')">suppress</button>
|
<button class="copybutton" onclick="copyText('$esc.html($dependency.FileNameForJavaScript)', '$esc.html($dependency.Sha1sum)', 'cpe', '$esc.html($id.value)')">suppress</button>
|
||||||
#end
|
#end
|
||||||
#if ($id.description)
|
#if ($id.description)
|
||||||
<br/>$esc.html($id.description)
|
<br/>$esc.html($id.description)
|
||||||
@@ -602,7 +613,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|||||||
<div id="content$cnt" class="subsectioncontent standardsubsection">
|
<div id="content$cnt" class="subsectioncontent standardsubsection">
|
||||||
#foreach($vuln in $dependency.getVulnerabilities())
|
#foreach($vuln in $dependency.getVulnerabilities())
|
||||||
#set($vsctr=$vsctr+1)
|
#set($vsctr=$vsctr+1)
|
||||||
<p><b><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=$esc.url($vuln.name)">$esc.html($vuln.name)</a></b> <button class="copybutton" onclick="copyText('$esc.html($dependency.FileName)', '$esc.html($dependency.Sha1sum)', 'cve', '$esc.html($vuln.name)')">suppress</button></p>
|
<p><b><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=$esc.url($vuln.name)">$esc.html($vuln.name)</a></b> <button class="copybutton" onclick="copyText('$esc.html($dependency.FileNameForJavaScript)', '$esc.html($dependency.Sha1sum)', 'cve', '$esc.html($vuln.name)')">suppress</button></p>
|
||||||
<p>Severity:
|
<p>Severity:
|
||||||
#if ($vuln.cvssScore<4.0)
|
#if ($vuln.cvssScore<4.0)
|
||||||
Low
|
Low
|
||||||
|
|||||||
@@ -161,11 +161,22 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
|||||||
margin-top:3px;
|
margin-top:3px;
|
||||||
margin-bottom:3px;
|
margin-bottom:3px;
|
||||||
}
|
}
|
||||||
|
.disclaimer {
|
||||||
|
color: #888888;
|
||||||
|
font: 9px "Droid Sans",Arial,"Helvetica Neue","Lucida Grande",sans-serif
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
<h1 class="sectionheader">Vulnerability Report</h1>
|
<h1 class="sectionheader">Vulnerability Report</h1>
|
||||||
|
<p class="disclaimer">Dependency-Check is an open source tool performing a best effort analysis of 3rd party dependencies;
|
||||||
|
false positives and false negatives may exist in the analysis performed by the tool. Use of the tool and
|
||||||
|
the reporting provided constitutes acceptance for use in an AS IS condition, and there are NO warranties,
|
||||||
|
implied or otherwise, with regard to the analysis or its use. Any use of the tool and the reporting provided
|
||||||
|
is at the user’s risk. In no event shall the copyright holder or OWASP be held liable for any damages whatsoever
|
||||||
|
arising out of or in connection with the use of this tool, the analysis performed, or the resulting report.</p>
|
||||||
]]#
|
]]#
|
||||||
<h2 class="sectionheader white">Project: $esc.html($applicationName)</h2>
|
<h2 class="sectionheader white">Project: $esc.html($applicationName)</h2>
|
||||||
<div class="sectioncontent">Report Generated On: $date<br/><br/>
|
<div class="sectioncontent">Report Generated On: $date<br/><br/>
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ import org.junit.BeforeClass;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -57,6 +59,26 @@ public class EngineIntegrationTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testScan() throws Exception {
|
public void testScan() throws Exception {
|
||||||
|
String testClasses = "target/test-classes/*.zip";
|
||||||
|
boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
|
||||||
|
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
|
||||||
|
Engine instance = new Engine();
|
||||||
|
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
|
||||||
|
instance.scan(testClasses);
|
||||||
|
assertTrue(instance.getDependencies().size() > 0);
|
||||||
|
for (Dependency d : instance.getDependencies()) {
|
||||||
|
assertTrue("non-zip file collected " + d.getFileName(), d.getFileName().toLowerCase().endsWith(".zip"));
|
||||||
|
}
|
||||||
|
instance.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test running the entire engine.
|
||||||
|
*
|
||||||
|
* @throws Exception is thrown when an exception occurs.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testEngine() throws Exception {
|
||||||
String testClasses = "target/test-classes";
|
String testClasses = "target/test-classes";
|
||||||
Engine instance = new Engine();
|
Engine instance = new Engine();
|
||||||
instance.scan(testClasses);
|
instance.scan(testClasses);
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ import org.junit.Test;
|
|||||||
*
|
*
|
||||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||||
*/
|
*/
|
||||||
public class AbstractAnalyzerTest {
|
public class AbstractFileTypeAnalyzerTest {
|
||||||
|
|
||||||
public AbstractAnalyzerTest() {
|
public AbstractFileTypeAnalyzerTest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
@@ -56,7 +56,7 @@ public class AbstractAnalyzerTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNewHashSet() {
|
public void testNewHashSet() {
|
||||||
Set result = AbstractAnalyzer.newHashSet("one", "two");
|
Set result = AbstractFileTypeAnalyzer.newHashSet("one", "two");
|
||||||
assertEquals(2, result.size());
|
assertEquals(2, result.size());
|
||||||
assertTrue(result.contains("one"));
|
assertTrue(result.contains("one"));
|
||||||
assertTrue(result.contains("two"));
|
assertTrue(result.contains("two"));
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* 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.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 org.junit.After;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.suppression.SuppressionRule;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||||
|
*/
|
||||||
|
public class AbstractSuppressionAnalyzerTest {
|
||||||
|
|
||||||
|
public AbstractSuppressionAnalyzerTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpClass() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void tearDownClass() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
try {
|
||||||
|
final String uri = this.getClass().getClassLoader().getResource("suppressions.xml").toURI().toURL().toString();
|
||||||
|
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, uri);
|
||||||
|
} catch (URISyntaxException ex) {
|
||||||
|
Logger.getLogger(AbstractSuppressionAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
} catch (MalformedURLException ex) {
|
||||||
|
Logger.getLogger(AbstractSuppressionAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AnalysisPhase getAnalysisPhase() {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -18,7 +18,6 @@
|
|||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
@@ -62,8 +61,7 @@ public class AnalyzerServiceTest {
|
|||||||
boolean found = false;
|
boolean found = false;
|
||||||
while (result.hasNext()) {
|
while (result.hasNext()) {
|
||||||
Analyzer a = result.next();
|
Analyzer a = result.next();
|
||||||
Set<String> e = a.getSupportedExtensions();
|
if ("Jar Analyzer".equals(a.getName())) {
|
||||||
if (e != null && e.contains("jar")) {
|
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import org.junit.Before;
|
|||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
import org.owasp.dependencycheck.data.cpe.BaseIndexTestCase;
|
import org.owasp.dependencycheck.data.cpe.AbstractDatabaseTestCase;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ import org.owasp.dependencycheck.utils.Settings;
|
|||||||
*
|
*
|
||||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||||
*/
|
*/
|
||||||
public class ArchiveAnalyzerTest extends BaseIndexTestCase {
|
public class ArchiveAnalyzerTest extends AbstractDatabaseTestCase {
|
||||||
|
|
||||||
public ArchiveAnalyzerTest() {
|
public ArchiveAnalyzerTest() {
|
||||||
}
|
}
|
||||||
@@ -147,6 +147,8 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testAnalyze() throws Exception {
|
public void testAnalyze() throws Exception {
|
||||||
ArchiveAnalyzer instance = new ArchiveAnalyzer();
|
ArchiveAnalyzer instance = new ArchiveAnalyzer();
|
||||||
|
//trick the analyzer into thinking it is active.
|
||||||
|
instance.supportsExtension("ear");
|
||||||
try {
|
try {
|
||||||
instance.initialize();
|
instance.initialize();
|
||||||
|
|
||||||
@@ -175,6 +177,8 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testAnalyzeTar() throws Exception {
|
public void testAnalyzeTar() throws Exception {
|
||||||
ArchiveAnalyzer instance = new ArchiveAnalyzer();
|
ArchiveAnalyzer instance = new ArchiveAnalyzer();
|
||||||
|
//trick the analyzer into thinking it is active so that it will initialize
|
||||||
|
instance.supportsExtension("tar");
|
||||||
try {
|
try {
|
||||||
instance.initialize();
|
instance.initialize();
|
||||||
|
|
||||||
@@ -203,6 +207,7 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testAnalyzeTarGz() throws Exception {
|
public void testAnalyzeTarGz() throws Exception {
|
||||||
ArchiveAnalyzer instance = new ArchiveAnalyzer();
|
ArchiveAnalyzer instance = new ArchiveAnalyzer();
|
||||||
|
instance.supportsExtension("zip"); //ensure analyzer is "enabled"
|
||||||
try {
|
try {
|
||||||
instance.initialize();
|
instance.initialize();
|
||||||
|
|
||||||
@@ -252,6 +257,7 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testAnalyzeTgz() throws Exception {
|
public void testAnalyzeTgz() throws Exception {
|
||||||
ArchiveAnalyzer instance = new ArchiveAnalyzer();
|
ArchiveAnalyzer instance = new ArchiveAnalyzer();
|
||||||
|
instance.supportsExtension("zip"); //ensure analyzer is "enabled"
|
||||||
try {
|
try {
|
||||||
instance.initialize();
|
instance.initialize();
|
||||||
|
|
||||||
|
|||||||
@@ -17,14 +17,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.junit.Assume.assumeFalse;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
import static org.junit.Assume.assumeFalse;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
@@ -54,6 +57,7 @@ public class AssemblyAnalyzerTest {
|
|||||||
public void setUp() {
|
public void setUp() {
|
||||||
try {
|
try {
|
||||||
analyzer = new AssemblyAnalyzer();
|
analyzer = new AssemblyAnalyzer();
|
||||||
|
analyzer.supportsExtension("dll");
|
||||||
analyzer.initialize();
|
analyzer.initialize();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.log(Level.WARNING, "Exception setting up AssemblyAnalyzer. Tests will be incomplete", e);
|
LOGGER.log(Level.WARNING, "Exception setting up AssemblyAnalyzer. Tests will be incomplete", e);
|
||||||
@@ -74,7 +78,21 @@ public class AssemblyAnalyzerTest {
|
|||||||
File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("GrokAssembly.exe").getPath());
|
File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("GrokAssembly.exe").getPath());
|
||||||
Dependency d = new Dependency(f);
|
Dependency d = new Dependency(f);
|
||||||
analyzer.analyze(d, null);
|
analyzer.analyze(d, null);
|
||||||
assertTrue(d.getVersionEvidence().getEvidence().contains(new Evidence("grokassembly", "version", "1.0.5140.29700", Confidence.HIGHEST)));
|
boolean foundVendor = false;
|
||||||
|
for (Evidence e : d.getVendorEvidence().getEvidence("grokassembly", "vendor")) {
|
||||||
|
if ("OWASP".equals(e.getValue())) {
|
||||||
|
foundVendor = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue(foundVendor);
|
||||||
|
|
||||||
|
boolean foundProduct = false;
|
||||||
|
for (Evidence e : d.getProductEvidence().getEvidence("grokassembly", "product")) {
|
||||||
|
if ("GrokAssembly".equals(e.getValue())) {
|
||||||
|
foundProduct = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue(foundProduct);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -87,15 +105,29 @@ public class AssemblyAnalyzerTest {
|
|||||||
assertTrue(d.getProductEvidence().getEvidence().contains(new Evidence("grokassembly", "product", "log4net", Confidence.HIGH)));
|
assertTrue(d.getProductEvidence().getEvidence().contains(new Evidence("grokassembly", "product", "log4net", Confidence.HIGH)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = AnalysisException.class)
|
@Test
|
||||||
public void testNonexistent() throws Exception {
|
public void testNonexistent() {
|
||||||
|
Level oldLevel = Logger.getLogger(AssemblyAnalyzer.class.getName()).getLevel();
|
||||||
|
Level oldDependency = Logger.getLogger(Dependency.class.getName()).getLevel();
|
||||||
|
// Tweak the log level so the warning doesn't show in the console
|
||||||
|
Logger.getLogger(AssemblyAnalyzer.class.getName()).setLevel(Level.OFF);
|
||||||
|
Logger.getLogger(Dependency.class.getName()).setLevel(Level.OFF);
|
||||||
File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath());
|
File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath());
|
||||||
File test = new File(f.getParent(), "nonexistent.dll");
|
File test = new File(f.getParent(), "nonexistent.dll");
|
||||||
Dependency d = new Dependency(test);
|
Dependency d = new Dependency(test);
|
||||||
analyzer.analyze(d, null);
|
|
||||||
|
try {
|
||||||
|
analyzer.analyze(d, null);
|
||||||
|
fail("Expected an AnalysisException");
|
||||||
|
} catch (AnalysisException ae) {
|
||||||
|
assertEquals("File does not exist", ae.getMessage());
|
||||||
|
} finally {
|
||||||
|
Logger.getLogger(AssemblyAnalyzer.class.getName()).setLevel(oldLevel);
|
||||||
|
Logger.getLogger(Dependency.class.getName()).setLevel(oldDependency);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = AnalysisException.class)
|
@Test
|
||||||
public void testWithSettingMono() throws Exception {
|
public void testWithSettingMono() throws Exception {
|
||||||
|
|
||||||
//This test doesn't work on Windows.
|
//This test doesn't work on Windows.
|
||||||
@@ -112,11 +144,20 @@ public class AssemblyAnalyzerTest {
|
|||||||
Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, "/yooser/bine/mono");
|
Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, "/yooser/bine/mono");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Level oldLevel = Logger.getLogger(AssemblyAnalyzer.class.getName()).getLevel();
|
||||||
try {
|
try {
|
||||||
|
// Tweak the logging to swallow the warning when testing
|
||||||
|
Logger.getLogger(AssemblyAnalyzer.class.getName()).setLevel(Level.OFF);
|
||||||
// Have to make a NEW analyzer because during setUp, it would have gotten the correct one
|
// Have to make a NEW analyzer because during setUp, it would have gotten the correct one
|
||||||
AssemblyAnalyzer aanalyzer = new AssemblyAnalyzer();
|
AssemblyAnalyzer aanalyzer = new AssemblyAnalyzer();
|
||||||
|
aanalyzer.supportsExtension("dll");
|
||||||
aanalyzer.initialize();
|
aanalyzer.initialize();
|
||||||
|
fail("Expected an AnalysisException");
|
||||||
|
} catch (AnalysisException ae) {
|
||||||
|
assertEquals("An error occured with the .NET AssemblyAnalyzer", ae.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
|
// Recover the logger
|
||||||
|
Logger.getLogger(AssemblyAnalyzer.class.getName()).setLevel(oldLevel);
|
||||||
// Now recover the way we came in. If we had to set a System property, delete it. Otherwise,
|
// Now recover the way we came in. If we had to set a System property, delete it. Otherwise,
|
||||||
// reset the old value
|
// reset the old value
|
||||||
if (oldValue == null) {
|
if (oldValue == null) {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import org.junit.Assert;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.owasp.dependencycheck.data.cpe.BaseIndexTestCase;
|
import org.owasp.dependencycheck.data.cpe.AbstractDatabaseTestCase;
|
||||||
import org.owasp.dependencycheck.data.cpe.IndexEntry;
|
import org.owasp.dependencycheck.data.cpe.IndexEntry;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.dependency.Identifier;
|
import org.owasp.dependencycheck.dependency.Identifier;
|
||||||
@@ -39,7 +39,7 @@ import org.owasp.dependencycheck.dependency.Identifier;
|
|||||||
*
|
*
|
||||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||||
*/
|
*/
|
||||||
public class CPEAnalyzerTest extends BaseIndexTestCase {
|
public class CPEAnalyzerTest extends AbstractDatabaseTestCase {
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUpClass() throws Exception {
|
public static void setUpClass() throws Exception {
|
||||||
|
|||||||
@@ -17,11 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -52,16 +50,6 @@ public class DependencyBundlingAnalyzerTest {
|
|||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test of getSupportedExtensions method, of class DependencyBundlingAnalyzer.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testGetSupportedExtensions() {
|
|
||||||
DependencyBundlingAnalyzer instance = new DependencyBundlingAnalyzer();
|
|
||||||
Set<String> result = instance.getSupportedExtensions();
|
|
||||||
assertNull(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test of getName method, of class DependencyBundlingAnalyzer.
|
* Test of getName method, of class DependencyBundlingAnalyzer.
|
||||||
*/
|
*/
|
||||||
@@ -73,18 +61,6 @@ public class DependencyBundlingAnalyzerTest {
|
|||||||
assertEquals(expResult, result);
|
assertEquals(expResult, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test of supportsExtension method, of class DependencyBundlingAnalyzer.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testSupportsExtension() {
|
|
||||||
String extension = "jar";
|
|
||||||
DependencyBundlingAnalyzer instance = new DependencyBundlingAnalyzer();
|
|
||||||
boolean expResult = true;
|
|
||||||
boolean result = instance.supportsExtension(extension);
|
|
||||||
assertEquals(expResult, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test of getAnalysisPhase method, of class DependencyBundlingAnalyzer.
|
* Test of getAnalysisPhase method, of class DependencyBundlingAnalyzer.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -15,11 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
@@ -52,17 +50,6 @@ public class FalsePositiveAnalyzerTest {
|
|||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test of getSupportedExtensions method, of class FalsePositiveAnalyzer.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testGetSupportedExtensions() {
|
|
||||||
FalsePositiveAnalyzer instance = new FalsePositiveAnalyzer();
|
|
||||||
Set<String> result = instance.getSupportedExtensions();
|
|
||||||
assertNull(result);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test of getName method, of class FalsePositiveAnalyzer.
|
* Test of getName method, of class FalsePositiveAnalyzer.
|
||||||
*/
|
*/
|
||||||
@@ -74,18 +61,6 @@ public class FalsePositiveAnalyzerTest {
|
|||||||
assertEquals(expResult, result);
|
assertEquals(expResult, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test of supportsExtension method, of class FalsePositiveAnalyzer.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testSupportsExtension() {
|
|
||||||
String extension = "any";
|
|
||||||
FalsePositiveAnalyzer instance = new FalsePositiveAnalyzer();
|
|
||||||
boolean expResult = true;
|
|
||||||
boolean result = instance.supportsExtension(extension);
|
|
||||||
assertEquals(expResult, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test of getAnalysisPhase method, of class FalsePositiveAnalyzer.
|
* Test of getAnalysisPhase method, of class FalsePositiveAnalyzer.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Set;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@@ -53,17 +52,6 @@ public class FileNameAnalyzerTest {
|
|||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test of getSupportedExtensions method, of class FileNameAnalyzer.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testGetSupportedExtensions() {
|
|
||||||
FileNameAnalyzer instance = new FileNameAnalyzer();
|
|
||||||
Set expResult = null;
|
|
||||||
Set result = instance.getSupportedExtensions();
|
|
||||||
assertEquals(expResult, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test of getName method, of class FileNameAnalyzer.
|
* Test of getName method, of class FileNameAnalyzer.
|
||||||
*/
|
*/
|
||||||
@@ -75,18 +63,6 @@ public class FileNameAnalyzerTest {
|
|||||||
assertEquals(expResult, result);
|
assertEquals(expResult, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test of supportsExtension method, of class FileNameAnalyzer.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testSupportsExtension() {
|
|
||||||
String extension = "any";
|
|
||||||
FileNameAnalyzer instance = new FileNameAnalyzer();
|
|
||||||
boolean expResult = true;
|
|
||||||
boolean result = instance.supportsExtension(extension);
|
|
||||||
assertEquals(expResult, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test of getAnalysisPhase method, of class FileNameAnalyzer.
|
* Test of getAnalysisPhase method, of class FileNameAnalyzer.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,39 +17,43 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.analyzer;
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
public class NuspecAnalyzerTest {
|
public class NuspecAnalyzerTest {
|
||||||
private NuspecAnalyzer instance;
|
|
||||||
|
|
||||||
@Before
|
private NuspecAnalyzer instance;
|
||||||
public void setUp() {
|
|
||||||
instance = new NuspecAnalyzer();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Before
|
||||||
public void testGetAnalyzerName() {
|
public void setUp() {
|
||||||
assertEquals("Nuspec Analyzer", instance.getName());
|
instance = new NuspecAnalyzer();
|
||||||
}
|
instance.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetSupportedExtensions() {
|
public void testGetAnalyzerName() {
|
||||||
assertTrue(instance.getSupportedExtensions().contains("nuspec"));
|
assertEquals("Nuspec Analyzer", instance.getName());
|
||||||
assertFalse(instance.getSupportedExtensions().contains("nupkg"));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSupportsExtension() {
|
public void testGetSupportedExtensions() {
|
||||||
assertTrue(instance.supportsExtension("nuspec"));
|
assertTrue(instance.getSupportedExtensions().contains("nuspec"));
|
||||||
assertFalse(instance.supportsExtension("nupkg"));
|
assertFalse(instance.getSupportedExtensions().contains("nupkg"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetAnalysisPhaze() {
|
public void testSupportsExtension() {
|
||||||
assertEquals(AnalysisPhase.INFORMATION_COLLECTION, instance.getAnalysisPhase());
|
assertTrue(instance.supportsExtension("nuspec"));
|
||||||
}
|
assertFalse(instance.supportsExtension("nupkg"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAnalysisPhaze() {
|
||||||
|
assertEquals(AnalysisPhase.INFORMATION_COLLECTION, instance.getAnalysisPhase());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// vim: cc=120:sw=4:ts=4:sts=4
|
// vim: cc=120:sw=4:ts=4:sts=4
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* 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) 2014 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.analyzer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.owasp.dependencycheck.Engine;
|
||||||
|
import org.owasp.dependencycheck.data.cpe.AbstractDatabaseTestCase;
|
||||||
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing the vulnerability suppression analyzer.
|
||||||
|
*
|
||||||
|
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||||
|
*/
|
||||||
|
public class VulnerabilitySuppressionAnalyzerTest extends AbstractDatabaseTestCase {
|
||||||
|
|
||||||
|
public VulnerabilitySuppressionAnalyzerTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpClass() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void tearDownClass() {
|
||||||
|
}
|
||||||
|
private boolean update = true;
|
||||||
|
private boolean nexus = false;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
update = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
|
||||||
|
nexus = Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED);
|
||||||
|
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
@Override
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
super.tearDown();
|
||||||
|
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, update);
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of getName method, of class VulnerabilitySuppressionAnalyzer.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetName() {
|
||||||
|
VulnerabilitySuppressionAnalyzer instance = new VulnerabilitySuppressionAnalyzer();
|
||||||
|
String expResult = "Vulnerability Suppression Analyzer";
|
||||||
|
String result = instance.getName();
|
||||||
|
assertEquals(expResult, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of getAnalysisPhase method, of class VulnerabilitySuppressionAnalyzer.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetAnalysisPhase() {
|
||||||
|
VulnerabilitySuppressionAnalyzer instance = new VulnerabilitySuppressionAnalyzer();
|
||||||
|
AnalysisPhase expResult = AnalysisPhase.POST_FINDING_ANALYSIS;;
|
||||||
|
AnalysisPhase result = instance.getAnalysisPhase();
|
||||||
|
assertEquals(expResult, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of analyze method, of class VulnerabilitySuppressionAnalyzer.
|
||||||
|
*/
|
||||||
|
@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());
|
||||||
|
|
||||||
|
Engine engine = new Engine();
|
||||||
|
engine.scan(file);
|
||||||
|
engine.analyzeDependencies();
|
||||||
|
Dependency dependency = getDependency(engine, file);
|
||||||
|
assertTrue(dependency.getVulnerabilities().size() > 0);
|
||||||
|
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppression.getAbsolutePath());
|
||||||
|
VulnerabilitySuppressionAnalyzer instance = new VulnerabilitySuppressionAnalyzer();
|
||||||
|
instance.initialize();
|
||||||
|
instance.analyze(dependency, engine);
|
||||||
|
assertTrue(dependency.getVulnerabilities().size() == 0);
|
||||||
|
engine.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a specific dependency from the engine.
|
||||||
|
*
|
||||||
|
* @param engine the engine
|
||||||
|
* @param file the dependency to retrieve
|
||||||
|
* @return the dependency
|
||||||
|
*/
|
||||||
|
private Dependency getDependency(Engine engine, File file) {
|
||||||
|
for (Dependency d : engine.getDependencies()) {
|
||||||
|
if (d.getFileName().equals(file.getName())) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,10 +25,12 @@ import org.junit.BeforeClass;
|
|||||||
import org.owasp.dependencycheck.data.nvdcve.BaseDBTestCase;
|
import org.owasp.dependencycheck.data.nvdcve.BaseDBTestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* An abstract database test case that is used to ensure the H2 DB exists prior to performing tests that utilize the
|
||||||
|
* data contained within.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long <jeremy.long@owasp.org>
|
* @author Jeremy Long <jeremy.long@owasp.org>
|
||||||
*/
|
*/
|
||||||
public abstract class BaseIndexTestCase extends TestCase {
|
public abstract class AbstractDatabaseTestCase extends TestCase {
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUpClass() throws Exception {
|
public static void setUpClass() throws Exception {
|
||||||
@@ -73,7 +73,7 @@ public class FileUtilsTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testDelete() throws Exception {
|
public void testDelete() throws Exception {
|
||||||
|
|
||||||
File file = File.createTempFile("tmp", "deleteme");
|
File file = File.createTempFile("tmp", "deleteme", Settings.getTempDirectory());
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
fail("Unable to create a temporary file.");
|
fail("Unable to create a temporary file.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,6 +155,11 @@ public class SettingsTest {
|
|||||||
boolean expResult = false;
|
boolean expResult = false;
|
||||||
boolean result = Settings.getBoolean(key);
|
boolean result = Settings.getBoolean(key);
|
||||||
Assert.assertEquals(expResult, result);
|
Assert.assertEquals(expResult, result);
|
||||||
|
|
||||||
|
key = "something that does not exist";
|
||||||
|
expResult = true;
|
||||||
|
result = Settings.getBoolean(key, true);
|
||||||
|
Assert.assertEquals(expResult, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,10 @@
|
|||||||
|
<?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>
|
||||||
@@ -49,7 +49,7 @@ 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
|
# the URL for searching Nexus for SHA-1 hashes and whether it's enabled
|
||||||
analyzer.nexus.enabled=true
|
analyzer.nexus.enabled=true
|
||||||
analyzer.nexus.url=http://repository.sonatype.org/service/local/
|
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)
|
# If set to true, the proxy will still ONLY be used if the proxy properties (proxy.url, proxy.port)
|
||||||
# are configured
|
# are configured
|
||||||
analyzer.nexus.proxy=true
|
analyzer.nexus.proxy=true
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-parent</artifactId>
|
<artifactId>dependency-check-parent</artifactId>
|
||||||
<version>1.1.2</version>
|
<version>1.1.4</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-parent</artifactId>
|
<artifactId>dependency-check-parent</artifactId>
|
||||||
<version>1.1.2</version>
|
<version>1.1.4</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>dependency-check-maven</artifactId>
|
<artifactId>dependency-check-maven</artifactId>
|
||||||
@@ -275,6 +275,11 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
|||||||
<artifactId>maven-plugin-api</artifactId>
|
<artifactId>maven-plugin-api</artifactId>
|
||||||
<version>3.0</version>
|
<version>3.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.maven</groupId>
|
||||||
|
<artifactId>maven-settings</artifactId>
|
||||||
|
<version>3.0</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven</groupId>
|
<groupId>org.apache.maven</groupId>
|
||||||
<artifactId>maven-core</artifactId>
|
<artifactId>maven-core</artifactId>
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import org.apache.maven.project.MavenProject;
|
|||||||
import org.apache.maven.reporting.MavenMultiPageReport;
|
import org.apache.maven.reporting.MavenMultiPageReport;
|
||||||
import org.apache.maven.reporting.MavenReport;
|
import org.apache.maven.reporting.MavenReport;
|
||||||
import org.apache.maven.reporting.MavenReportException;
|
import org.apache.maven.reporting.MavenReportException;
|
||||||
|
import org.apache.maven.settings.Proxy;
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||||
@@ -87,48 +88,45 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
@Component
|
@Component
|
||||||
private MavenProject project;
|
private MavenProject project;
|
||||||
/**
|
/**
|
||||||
* The name of the site report destination.
|
* The path to the verbose log.
|
||||||
*/
|
|
||||||
@Parameter(property = "report-name", defaultValue = "dependency-check-report")
|
|
||||||
private String reportName;
|
|
||||||
/**
|
|
||||||
* The path to the verbose log
|
|
||||||
*/
|
*/
|
||||||
@Parameter(property = "logfile", defaultValue = "")
|
@Parameter(property = "logfile", defaultValue = "")
|
||||||
private String logFile;
|
private String logFile;
|
||||||
/**
|
/**
|
||||||
* The name of the report to be displayed in the Maven Generated Reports page
|
* The name of the report to be displayed in the Maven Generated Reports page.
|
||||||
*/
|
*/
|
||||||
@Parameter(property = "name", defaultValue = "Dependency-Check")
|
@Parameter(property = "name", defaultValue = "Dependency-Check")
|
||||||
private String name;
|
private String name;
|
||||||
/**
|
/**
|
||||||
* The description of the Dependency-Check report to be displayed in the Maven Generated Reports page
|
* The description of the Dependency-Check report to be displayed in the Maven Generated Reports page.
|
||||||
*/
|
*/
|
||||||
@Parameter(property = "description", defaultValue = "A report providing details on any published "
|
@Parameter(property = "description", defaultValue = "A report providing details on any published "
|
||||||
+ "vulnerabilities within project dependencies. This report is a best effort but may contain "
|
+ "vulnerabilities within project dependencies. This report is a best effort but may contain "
|
||||||
+ "false positives and false negatives.")
|
+ "false positives and false negatives.")
|
||||||
private String description;
|
private String description;
|
||||||
/**
|
/**
|
||||||
* Specifies the destination directory for the generated Dependency-Check report.
|
* Specifies the destination directory for the generated Dependency-Check report. This generally maps to
|
||||||
|
* "target/site".
|
||||||
*/
|
*/
|
||||||
@Parameter(property = "reportOutputDirectory", defaultValue = "${project.reporting.outputDirectory}", required = true)
|
@Parameter(property = "reportOutputDirectory", defaultValue = "${project.reporting.outputDirectory}", required = true)
|
||||||
private File reportOutputDirectory;
|
private File reportOutputDirectory;
|
||||||
/**
|
/**
|
||||||
* Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11
|
* The output directory. This generally maps to "target".
|
||||||
* which means since the CVSS scores are 0-10, by default the build will never fail.
|
|
||||||
*/
|
|
||||||
@Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true)
|
|
||||||
private float failBuildOnCVSS = 11;
|
|
||||||
/**
|
|
||||||
* The output directory.
|
|
||||||
*/
|
*/
|
||||||
@Parameter(defaultValue = "${project.build.directory}", required = true)
|
@Parameter(defaultValue = "${project.build.directory}", required = true)
|
||||||
private File outputDirectory;
|
private File outputDirectory;
|
||||||
|
/**
|
||||||
|
* Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11
|
||||||
|
* which means since the CVSS scores are 0-10, by default the build will never fail.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("CanBeFinal")
|
||||||
|
@Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true)
|
||||||
|
private float failBuildOnCVSS = 11;
|
||||||
/**
|
/**
|
||||||
* Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to
|
* Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to
|
||||||
* false. Default is true.
|
* false. Default is true.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
@SuppressWarnings("CanBeFinal")
|
||||||
@Parameter(property = "autoupdate", defaultValue = "true", required = true)
|
@Parameter(property = "autoupdate", defaultValue = "true", required = true)
|
||||||
private boolean autoUpdate = true;
|
private boolean autoUpdate = true;
|
||||||
/**
|
/**
|
||||||
@@ -146,27 +144,54 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
private boolean externalReport = false;
|
private boolean externalReport = false;
|
||||||
/**
|
/**
|
||||||
* The Proxy URL.
|
* The Proxy URL.
|
||||||
|
*
|
||||||
|
* @deprecated Please use mavenSettings instead
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||||
@Parameter(property = "proxyUrl", defaultValue = "", required = false)
|
@Parameter(property = "proxyUrl", defaultValue = "", required = false)
|
||||||
|
@Deprecated
|
||||||
private String proxyUrl = null;
|
private String proxyUrl = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maven settings.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||||
|
@Parameter(property = "mavenSettings", defaultValue = "${settings}", required = false)
|
||||||
|
private org.apache.maven.settings.Settings mavenSettings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maven settings proxy id.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||||
|
@Parameter(property = "mavenSettingsProxyId", required = false)
|
||||||
|
private String mavenSettingsProxyId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Proxy Port.
|
* The Proxy Port.
|
||||||
|
*
|
||||||
|
* @deprecated Please use mavenSettings instead
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||||
@Parameter(property = "proxyPort", defaultValue = "", required = false)
|
@Parameter(property = "proxyPort", defaultValue = "", required = false)
|
||||||
|
@Deprecated
|
||||||
private String proxyPort = null;
|
private String proxyPort = null;
|
||||||
/**
|
/**
|
||||||
* The Proxy username.
|
* The Proxy username.
|
||||||
|
*
|
||||||
|
* @deprecated Please use mavenSettings instead
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||||
@Parameter(property = "proxyUsername", defaultValue = "", required = false)
|
@Parameter(property = "proxyUsername", defaultValue = "", required = false)
|
||||||
|
@Deprecated
|
||||||
private String proxyUsername = null;
|
private String proxyUsername = null;
|
||||||
/**
|
/**
|
||||||
* The Proxy password.
|
* The Proxy password.
|
||||||
|
*
|
||||||
|
* @deprecated Please use mavenSettings instead
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||||
@Parameter(property = "proxyPassword", defaultValue = "", required = false)
|
@Parameter(property = "proxyPassword", defaultValue = "", required = false)
|
||||||
|
@Deprecated
|
||||||
private String proxyPassword = null;
|
private String proxyPassword = null;
|
||||||
/**
|
/**
|
||||||
* The Connection Timeout.
|
* The Connection Timeout.
|
||||||
@@ -186,6 +211,35 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||||
@Parameter(property = "showSummary", defaultValue = "true", required = false)
|
@Parameter(property = "showSummary", defaultValue = "true", required = false)
|
||||||
private boolean showSummary = true;
|
private boolean showSummary = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the Jar Analyzer is enabled.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||||
|
@Parameter(property = "jarAnalyzerEnabled", defaultValue = "true", required = false)
|
||||||
|
private boolean jarAnalyzerEnabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the Archive Analyzer is enabled.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||||
|
@Parameter(property = "archiveAnalyzerEnabled", defaultValue = "true", required = false)
|
||||||
|
private boolean archiveAnalyzerEnabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the .NET Assembly Analyzer is enabled.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||||
|
@Parameter(property = "assemblyAnalyzerEnabled", defaultValue = "true", required = false)
|
||||||
|
private boolean assemblyAnalyzerEnabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the .NET Nuspec Analyzer is enabled.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal"})
|
||||||
|
@Parameter(property = "nuspecAnalyzerEnabled", defaultValue = "true", required = false)
|
||||||
|
private boolean nuspecAnalyzerEnabled = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not the Nexus Analyzer is enabled.
|
* Whether or not the Nexus Analyzer is enabled.
|
||||||
*/
|
*/
|
||||||
@@ -240,18 +294,21 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
@Parameter(property = "zipExtensions", required = false)
|
@Parameter(property = "zipExtensions", required = false)
|
||||||
private String zipExtensions;
|
private String zipExtensions;
|
||||||
/**
|
/**
|
||||||
* Skip Analisys for Test Scope Dependencies
|
* Skip Analisys for Test Scope Dependencies.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("CanBeFinal")
|
||||||
@Parameter(property = "skipTestScope", defaultValue = "true", required = false)
|
@Parameter(property = "skipTestScope", defaultValue = "true", required = false)
|
||||||
private boolean skipTestScope = true;
|
private boolean skipTestScope = true;
|
||||||
/**
|
/**
|
||||||
* Skip Analisys for Runtime Scope Dependencies
|
* Skip Analisys for Runtime Scope Dependencies.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("CanBeFinal")
|
||||||
@Parameter(property = "skipRuntimeScope", defaultValue = "false", required = false)
|
@Parameter(property = "skipRuntimeScope", defaultValue = "false", required = false)
|
||||||
private boolean skipRuntimeScope = false;
|
private boolean skipRuntimeScope = false;
|
||||||
/**
|
/**
|
||||||
* Skip Analisys for Provided Scope Dependencies
|
* Skip Analisys for Provided Scope Dependencies.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("CanBeFinal")
|
||||||
@Parameter(property = "skipProvidedScope", defaultValue = "false", required = false)
|
@Parameter(property = "skipProvidedScope", defaultValue = "false", required = false)
|
||||||
private boolean skipProvidedScope = false;
|
private boolean skipProvidedScope = false;
|
||||||
/**
|
/**
|
||||||
@@ -260,26 +317,32 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
@Parameter(property = "dataDirectory", defaultValue = "", required = false)
|
@Parameter(property = "dataDirectory", defaultValue = "", required = false)
|
||||||
private String dataDirectory;
|
private String dataDirectory;
|
||||||
/**
|
/**
|
||||||
* Data Mirror URL for CVE 1.2
|
* Data Mirror URL for CVE 1.2.
|
||||||
*/
|
*/
|
||||||
@Parameter(property = "cveUrl12Modified", defaultValue = "", required = false)
|
@Parameter(property = "cveUrl12Modified", defaultValue = "", required = false)
|
||||||
private String cveUrl12Modified;
|
private String cveUrl12Modified;
|
||||||
/**
|
/**
|
||||||
* Data Mirror URL for CVE 2.0
|
* Data Mirror URL for CVE 2.0.
|
||||||
*/
|
*/
|
||||||
@Parameter(property = "cveUrl20Modified", defaultValue = "", required = false)
|
@Parameter(property = "cveUrl20Modified", defaultValue = "", required = false)
|
||||||
private String cveUrl20Modified;
|
private String cveUrl20Modified;
|
||||||
/**
|
/**
|
||||||
* Base Data Mirror URL for CVE 1.2
|
* Base Data Mirror URL for CVE 1.2.
|
||||||
*/
|
*/
|
||||||
@Parameter(property = "cveUrl12Base", defaultValue = "", required = false)
|
@Parameter(property = "cveUrl12Base", defaultValue = "", required = false)
|
||||||
private String cveUrl12Base;
|
private String cveUrl12Base;
|
||||||
/**
|
/**
|
||||||
* Data Mirror URL for CVE 2.0
|
* Data Mirror URL for CVE 2.0.
|
||||||
*/
|
*/
|
||||||
@Parameter(property = "cveUrl20Base", defaultValue = "", required = false)
|
@Parameter(property = "cveUrl20Base", defaultValue = "", required = false)
|
||||||
private String cveUrl20Base;
|
private String cveUrl20Base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path to mono for .NET Assembly analysis on non-windows systems.
|
||||||
|
*/
|
||||||
|
@Parameter(property = "pathToMono", defaultValue = "", required = false)
|
||||||
|
private String pathToMono;
|
||||||
|
|
||||||
// </editor-fold>
|
// </editor-fold>
|
||||||
/**
|
/**
|
||||||
* Executes the Dependency-Check on the dependent libraries.
|
* Executes the Dependency-Check on the dependent libraries.
|
||||||
@@ -325,8 +388,9 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
* Generates the reports for a given dependency-check engine.
|
* Generates the reports for a given dependency-check engine.
|
||||||
*
|
*
|
||||||
* @param engine a dependency-check engine
|
* @param engine a dependency-check engine
|
||||||
|
* @param outDirectory the directory to write the reports to
|
||||||
*/
|
*/
|
||||||
private void generateExternalReports(Engine engine) {
|
private void generateExternalReports(Engine engine, File outDirectory) {
|
||||||
DatabaseProperties prop = null;
|
DatabaseProperties prop = null;
|
||||||
CveDB cve = null;
|
CveDB cve = null;
|
||||||
try {
|
try {
|
||||||
@@ -342,7 +406,7 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
}
|
}
|
||||||
final ReportGenerator r = new ReportGenerator(project.getName(), engine.getDependencies(), engine.getAnalyzers(), prop);
|
final ReportGenerator r = new ReportGenerator(project.getName(), engine.getDependencies(), engine.getAnalyzers(), prop);
|
||||||
try {
|
try {
|
||||||
r.generateReports(outputDirectory.getCanonicalPath(), format);
|
r.generateReports(outDirectory.getCanonicalPath(), format);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.SEVERE,
|
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.SEVERE,
|
||||||
"Unexpected exception occurred during analysis; please see the verbose error log for more details.");
|
"Unexpected exception occurred during analysis; please see the verbose error log for more details.");
|
||||||
@@ -711,6 +775,41 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
}
|
}
|
||||||
// </editor-fold>
|
// </editor-fold>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maven settings proxy url.
|
||||||
|
*
|
||||||
|
* @param proxy the maven proxy
|
||||||
|
* @return the proxy url
|
||||||
|
*/
|
||||||
|
private String getMavenSettingsProxyUrl(Proxy proxy) {
|
||||||
|
return new StringBuilder(proxy.getProtocol()).append("://").append(proxy.getHost()).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maven proxy.
|
||||||
|
*
|
||||||
|
* @return the maven proxy
|
||||||
|
*/
|
||||||
|
private Proxy getMavenProxy() {
|
||||||
|
if (mavenSettings != null) {
|
||||||
|
final List<Proxy> proxies = mavenSettings.getProxies();
|
||||||
|
if (proxies != null && proxies.size() > 0) {
|
||||||
|
if (mavenSettingsProxyId != null) {
|
||||||
|
for (Proxy proxy : proxies) {
|
||||||
|
if (mavenSettingsProxyId.equalsIgnoreCase(proxy.getId())) {
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (proxies.size() == 1) {
|
||||||
|
return proxies.get(0);
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Ambigous proxy definition");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system
|
* 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 url, port, and connection timeout.
|
||||||
@@ -735,6 +834,18 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
|
|
||||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
|
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
|
||||||
|
|
||||||
|
final Proxy proxy = getMavenProxy();
|
||||||
|
if (proxy != null) {
|
||||||
|
Settings.setString(Settings.KEYS.PROXY_URL, getMavenSettingsProxyUrl(proxy));
|
||||||
|
Settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(proxy.getPort()));
|
||||||
|
final String userName = proxy.getUsername();
|
||||||
|
final String password = proxy.getPassword();
|
||||||
|
if (userName != null && password != null) {
|
||||||
|
Settings.setString(Settings.KEYS.PROXY_USERNAME, userName);
|
||||||
|
Settings.setString(Settings.KEYS.PROXY_PASSWORD, password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (proxyUrl != null && !proxyUrl.isEmpty()) {
|
if (proxyUrl != null && !proxyUrl.isEmpty()) {
|
||||||
Settings.setString(Settings.KEYS.PROXY_URL, proxyUrl);
|
Settings.setString(Settings.KEYS.PROXY_URL, proxyUrl);
|
||||||
}
|
}
|
||||||
@@ -753,11 +864,30 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
if (suppressionFile != null && !suppressionFile.isEmpty()) {
|
if (suppressionFile != null && !suppressionFile.isEmpty()) {
|
||||||
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
|
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//File Type Analyzer Settings
|
||||||
|
//JAR ANALYZER
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled);
|
||||||
|
//NUSPEC ANALYZER
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled);
|
||||||
|
//NEXUS ANALYZER
|
||||||
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
|
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
|
||||||
if (nexusUrl != null && !nexusUrl.isEmpty()) {
|
if (nexusUrl != null && !nexusUrl.isEmpty()) {
|
||||||
Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
|
Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
|
||||||
}
|
}
|
||||||
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy);
|
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy);
|
||||||
|
//ARCHIVE ANALYZER
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled);
|
||||||
|
if (zipExtensions != null && !zipExtensions.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
|
||||||
|
}
|
||||||
|
//ASSEMBLY ANALYZER
|
||||||
|
Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled);
|
||||||
|
if (pathToMono != null && !pathToMono.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Database configuration
|
||||||
if (databaseDriverName != null && !databaseDriverName.isEmpty()) {
|
if (databaseDriverName != null && !databaseDriverName.isEmpty()) {
|
||||||
Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
|
Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
|
||||||
}
|
}
|
||||||
@@ -773,8 +903,9 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
if (databasePassword != null && !databasePassword.isEmpty()) {
|
if (databasePassword != null && !databasePassword.isEmpty()) {
|
||||||
Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword);
|
Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword);
|
||||||
}
|
}
|
||||||
if (zipExtensions != null && !zipExtensions.isEmpty()) {
|
// Data Directory
|
||||||
Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
|
if (dataDirectory != null && !dataDirectory.isEmpty()) {
|
||||||
|
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scope Exclusion
|
// Scope Exclusion
|
||||||
@@ -782,11 +913,6 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
Settings.setBoolean(Settings.KEYS.SKIP_RUNTIME_SCOPE, skipRuntimeScope);
|
Settings.setBoolean(Settings.KEYS.SKIP_RUNTIME_SCOPE, skipRuntimeScope);
|
||||||
Settings.setBoolean(Settings.KEYS.SKIP_PROVIDED_SCOPE, skipProvidedScope);
|
Settings.setBoolean(Settings.KEYS.SKIP_PROVIDED_SCOPE, skipProvidedScope);
|
||||||
|
|
||||||
// Data Directory
|
|
||||||
if (dataDirectory != null && !dataDirectory.isEmpty()) {
|
|
||||||
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
|
|
||||||
}
|
|
||||||
|
|
||||||
// CVE Data Mirroring
|
// CVE Data Mirroring
|
||||||
if (cveUrl12Modified != null && !cveUrl12Modified.isEmpty()) {
|
if (cveUrl12Modified != null && !cveUrl12Modified.isEmpty()) {
|
||||||
Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
|
Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
|
||||||
@@ -800,6 +926,7 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
if (cveUrl20Base != null && !cveUrl20Base.isEmpty()) {
|
if (cveUrl20Base != null && !cveUrl20Base.isEmpty()) {
|
||||||
Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
|
Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -812,7 +939,7 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
Engine engine = null;
|
Engine engine = null;
|
||||||
try {
|
try {
|
||||||
engine = executeDependencyCheck();
|
engine = executeDependencyCheck();
|
||||||
generateExternalReports(engine);
|
generateExternalReports(engine, outputDirectory);
|
||||||
if (this.showSummary) {
|
if (this.showSummary) {
|
||||||
showSummary(engine.getDependencies());
|
showSummary(engine.getDependencies());
|
||||||
}
|
}
|
||||||
@@ -854,7 +981,11 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
Engine engine = null;
|
Engine engine = null;
|
||||||
try {
|
try {
|
||||||
engine = executeDependencyCheck();
|
engine = executeDependencyCheck();
|
||||||
generateMavenSiteReport(engine, sink);
|
if (this.externalReport) {
|
||||||
|
generateExternalReports(engine, reportOutputDirectory);
|
||||||
|
} else {
|
||||||
|
generateMavenSiteReport(engine, sink);
|
||||||
|
}
|
||||||
} catch (DatabaseException ex) {
|
} catch (DatabaseException ex) {
|
||||||
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.SEVERE,
|
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.SEVERE,
|
||||||
"Unable to connect to the dependency-check database; analysis has stopped");
|
"Unable to connect to the dependency-check database; analysis has stopped");
|
||||||
@@ -873,7 +1004,18 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
* @return the output name
|
* @return the output name
|
||||||
*/
|
*/
|
||||||
public String getOutputName() {
|
public String getOutputName() {
|
||||||
return reportName;
|
if ("HTML".equalsIgnoreCase(this.format)
|
||||||
|
|| "ALL".equalsIgnoreCase(this.format)) {
|
||||||
|
return "dependency-check-report";
|
||||||
|
} else if ("XML".equalsIgnoreCase(this.format)) {
|
||||||
|
return "dependency-check-report.xml#";
|
||||||
|
} else if ("VULN".equalsIgnoreCase(this.format)) {
|
||||||
|
return "dependency-check-vulnerability";
|
||||||
|
} else {
|
||||||
|
Logger.getLogger(DependencyCheckMojo.class
|
||||||
|
.getName()).log(Level.WARNING, "Unknown report format used during site generatation.");
|
||||||
|
return "dependency-check-report";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1009,7 +1151,9 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
|
|||||||
final String msg = String.format("%n%n"
|
final String msg = String.format("%n%n"
|
||||||
+ "One or more dependencies were identified with known vulnerabilities:%n%n%s"
|
+ "One or more dependencies were identified with known vulnerabilities:%n%n%s"
|
||||||
+ "%n%nSee the dependency-check report for more details.%n%n", summary.toString());
|
+ "%n%nSee the dependency-check report for more details.%n%n", summary.toString());
|
||||||
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.WARNING, msg);
|
Logger
|
||||||
|
.getLogger(DependencyCheckMojo.class
|
||||||
|
.getName()).log(Level.WARNING, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,29 +6,66 @@ Property | Description | Default Value
|
|||||||
---------------------|------------------------------------|------------------
|
---------------------|------------------------------------|------------------
|
||||||
autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. | true
|
autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. | true
|
||||||
externalReport | When using as a Site plugin this parameter sets whether or not the external report format should be used. | false
|
externalReport | When using as a Site plugin this parameter sets whether or not the external report format should be used. | false
|
||||||
|
outputDirectory | The location to write the report(s). Note, this is not used if generating the report as part of a `mvn site` build | 'target'
|
||||||
failBuildOnCVSS | Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which means since the CVSS scores are 0-10, by default the build will never fail. | 11
|
failBuildOnCVSS | Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which means since the CVSS scores are 0-10, by default the build will never fail. | 11
|
||||||
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
|
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. |
|
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) |
|
suppressionFile | The file path to the XML suppression file \- used to suppress [false positives](../suppression.html) |
|
||||||
connectionTimeout | The Connection Timeout. |
|
skipTestScope | Should be skip analysis for artifacts with Test Scope | true
|
||||||
proxyUrl | The Proxy URL. |
|
skipProvidedScope | Should be skip analysis for artifacts with Provided Scope | false
|
||||||
proxyPort | The Proxy Port. |
|
skipRuntimeScope | Should be skip analysis for artifacts with Runtime Scope | false
|
||||||
proxyUsername | Defines the proxy user name. |
|
|
||||||
proxyPassword | Defines the proxy password. |
|
Analyzer Configuration
|
||||||
nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. |
|
====================
|
||||||
nexusUrl | Defines the Nexus URL. |
|
The following properties are used to configure the various file type analyzers.
|
||||||
nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true
|
These properties can be used to turn off specific analyzers if it is not needed.
|
||||||
databaseDriverName | The name of the database driver. Example: org.h2.Driver. |
|
Note, that specific analyzers will automatically disable themselves if no file
|
||||||
databaseDriverPath | The path to the database driver JAR file; only used if the driver is not in the class path. |
|
types that they support are detected - so specifically disabling them may not
|
||||||
connectionString | The connection string used to connect to the database. |
|
be needed.
|
||||||
databaseUser | The username used when connecting to the database. |
|
|
||||||
databasePassword | The password used when connecting to the database. |
|
Property | Description | Default Value
|
||||||
zipExtensions | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |
|
------------------------|------------------------------------|------------------
|
||||||
skipTestScope | Should be skip analysis for artifacts with Test Scope | true
|
archiveAnalyzerEnabled | Sets whether the Archive Analyzer will be used. | true
|
||||||
skipProvidedScope | Should be skip analysis for artifacts with Provided Scope | false
|
zipExtensions | A comma-separated list of additional file extensions to be treated like a ZIP file, the contents will be extracted and analyzed. |
|
||||||
skipRuntimeScope | Should be skip analysis for artifacts with Runtime Scope | false
|
jarAnalyzer | Sets whether Jar Analyzer will be used. | true
|
||||||
dataDirectory | Data directory to hold SQL CVEs contents. This should generally not be changed. |
|
nexusAnalyzerEnabled | Sets whether Nexus Analyzer will be used. | true
|
||||||
cveUrl12Modified | URL for the modified CVE 1.2 | http://nvd.nist.gov/download/nvdcve-modified.xml
|
nexusUrl | Defines the Nexus URL. | https://repository.sonatype.org/service/local/
|
||||||
cveUrl20Modified | URL for the modified CVE 2.0 | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
|
nexusUsesProxy | Whether or not the defined proxy should be used when connecting to Nexus. | true
|
||||||
cveUrl12Base | Base URL for each year's CVE 1.2, the %d will be replaced with the year | http://nvd.nist.gov/download/nvdcve-%d.xml
|
nuspecAnalyzerEnabled | Sets whether or not the .NET Nuget Nuspec Analyzer will be used. | true
|
||||||
cveUrl20Base | Base URL for each year's CVE 2.0, the %d will be replaced with the year | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
|
assemblyAnalyzerEnabled | Sets whether or not the .NET Assembly Analyzer should be used. | true
|
||||||
|
pathToMono | The path to Mono for .NET assembly analysis on non-windows systems |
|
||||||
|
|
||||||
|
Advanced Configuration
|
||||||
|
====================
|
||||||
|
The following properties can be configured in the plugin. However, they are less frequently changed. One exception
|
||||||
|
may be the cvedUrl properties, which can be used to host a mirror of the NVD within an enterprise environment.
|
||||||
|
|
||||||
|
Property | Description | Default Value
|
||||||
|
---------------------|-------------------------------------------------------------------------|------------------
|
||||||
|
cveUrl12Modified | URL for the modified CVE 1.2 | http://nvd.nist.gov/download/nvdcve-modified.xml
|
||||||
|
cveUrl20Modified | URL for the modified CVE 2.0 | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
|
||||||
|
cveUrl12Base | Base URL for each year's CVE 1.2, the %d will be replaced with the year | http://nvd.nist.gov/download/nvdcve-%d.xml
|
||||||
|
cveUrl20Base | Base URL for each year's CVE 2.0, the %d will be replaced with the year | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
|
||||||
|
connectionTimeout | The URL Connection Timeout. |
|
||||||
|
dataDirectory | Data directory to hold SQL CVEs contents. This should generally not be changed. |
|
||||||
|
databaseDriverName | The name of the database driver. Example: org.h2.Driver. |
|
||||||
|
databaseDriverPath | The path to the database driver JAR file; only used if the driver is not in the class path. |
|
||||||
|
connectionString | The connection string used to connect to the database. |
|
||||||
|
databaseUser | The username used when connecting to the database. |
|
||||||
|
databasePassword | The password used when connecting to the database. |
|
||||||
|
|
||||||
|
|
||||||
|
Deprecated Configuration
|
||||||
|
====================
|
||||||
|
The following properties have been deprecated. These can stell 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. |
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ Vulnerability Database (NVD) hosted by NIST: https://nvd.nist.gov
|
|||||||
After the first batch download, as long as the plugin is executed at least once every
|
After the first batch download, as long as the plugin is executed at least once every
|
||||||
seven days the update will only take a few seconds.
|
seven days the update will only take a few seconds.
|
||||||
|
|
||||||
Example 1:
|
#set( $H = '#' )
|
||||||
---------------------
|
|
||||||
|
$H$H$H Example 1:
|
||||||
Create the DependencyCheck-report.html in the target directory
|
Create the DependencyCheck-report.html in the target directory
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
@@ -39,8 +40,7 @@ Create the DependencyCheck-report.html in the target directory
|
|||||||
</project>
|
</project>
|
||||||
```
|
```
|
||||||
|
|
||||||
Example 2:
|
$H$H$H Example 2:
|
||||||
---------------------
|
|
||||||
Create the DependencyCheck-report.html and fail the build for CVSS greater then 8
|
Create the DependencyCheck-report.html and fail the build for CVSS greater then 8
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
@@ -71,8 +71,7 @@ Create the DependencyCheck-report.html and fail the build for CVSS greater then
|
|||||||
</project>
|
</project>
|
||||||
```
|
```
|
||||||
|
|
||||||
Example 3:
|
$H$H$H Example 3:
|
||||||
---------------------
|
|
||||||
Create the dependency-check report within the site
|
Create the dependency-check report within the site
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
@@ -103,8 +102,8 @@ Create the dependency-check report within the site
|
|||||||
...
|
...
|
||||||
</project>
|
</project>
|
||||||
```
|
```
|
||||||
Example 4:
|
|
||||||
---------------------
|
$H$H$H Example 4:
|
||||||
Create the DependencyCheck-report.html and skip artifacts no bundled in distribution (Provided and Runtime scope)
|
Create the DependencyCheck-report.html and skip artifacts no bundled in distribution (Provided and Runtime scope)
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
@@ -135,8 +134,8 @@ Create the DependencyCheck-report.html and skip artifacts no bundled in distribu
|
|||||||
...
|
...
|
||||||
</project>
|
</project>
|
||||||
```
|
```
|
||||||
Example 5:
|
|
||||||
---------------------
|
$H$H$H Example 5:
|
||||||
Create the DependencyCheck-report.html and use internal mirroring of CVE contents
|
Create the DependencyCheck-report.html and use internal mirroring of CVE contents
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
@@ -169,4 +168,3 @@ Create the DependencyCheck-report.html and use internal mirroring of CVE content
|
|||||||
...
|
...
|
||||||
</project>
|
</project>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long
|
|||||||
|
|
||||||
<groupId>org.owasp</groupId>
|
<groupId>org.owasp</groupId>
|
||||||
<artifactId>dependency-check-parent</artifactId>
|
<artifactId>dependency-check-parent</artifactId>
|
||||||
<version>1.1.2</version>
|
<version>1.1.4</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 4.1 KiB |
@@ -50,7 +50,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
|||||||
title="built with maven"
|
title="built with maven"
|
||||||
alt="built with maven"
|
alt="built with maven"
|
||||||
img="http://jeremylong.github.io/DependencyCheck/images/logos/maven-feather.png"/>
|
img="http://jeremylong.github.io/DependencyCheck/images/logos/maven-feather.png"/>
|
||||||
<logo name="IntelliJ" href="http://maven.apache.org/"
|
<logo name="IntelliJ" href="http://www.jetbrains.com/idea/"
|
||||||
title="developed using" width="170px"
|
title="developed using" width="170px"
|
||||||
alt="developed using"
|
alt="developed using"
|
||||||
img="http://jeremylong.github.io/DependencyCheck/images/logos/logo_intellij_idea.png"/>
|
img="http://jeremylong.github.io/DependencyCheck/images/logos/logo_intellij_idea.png"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user