mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-01-14 15:53:36 +01:00
Compare commits
78 Commits
issue690_t
...
reportGene
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e4d012a69 | ||
|
|
dccbd659ed | ||
|
|
1b84095c0e | ||
|
|
c96ef88222 | ||
|
|
0540474e0c | ||
|
|
2dbfba9ac5 | ||
|
|
8eff628303 | ||
|
|
519167bf0f | ||
|
|
e8e06d12c7 | ||
|
|
006224b52c | ||
|
|
6007be1b5f | ||
|
|
6b5cfe1560 | ||
|
|
f584be7f44 | ||
|
|
b6a7d0ee9b | ||
|
|
1402b20a6b | ||
|
|
898412eaea | ||
|
|
7753b6f3c1 | ||
|
|
ea93f315d5 | ||
|
|
7f9cf5bb14 | ||
|
|
c4fe921670 | ||
|
|
693c08cfd3 | ||
|
|
9776f38b97 | ||
|
|
ff91d7cda7 | ||
|
|
e218b8ad70 | ||
|
|
555b1dc1cc | ||
|
|
523eed9319 | ||
|
|
9c7f6daf75 | ||
|
|
f2037b3fab | ||
|
|
c545285f7f | ||
|
|
290cd0507e | ||
|
|
ee72f172d2 | ||
|
|
e721dac389 | ||
|
|
4c15993a44 | ||
|
|
8fc42078c7 | ||
|
|
06d6fe4bd6 | ||
|
|
96cda322a3 | ||
|
|
0c991af58d | ||
|
|
3677b5f429 | ||
|
|
fd0abd9066 | ||
|
|
abb10600f7 | ||
|
|
c9a6bb4b16 | ||
|
|
9ff0042527 | ||
|
|
0504f9c4cc | ||
|
|
7b7861206b | ||
|
|
6f9207fe25 | ||
|
|
de6cd3621b | ||
|
|
04b506662f | ||
|
|
c1250fc53e | ||
|
|
c2f521f528 | ||
|
|
5fde08b001 | ||
|
|
69d621b981 | ||
|
|
4134fb3fef | ||
|
|
81b2b966ba | ||
|
|
ae65ebe687 | ||
|
|
03f84fa77e | ||
|
|
ff6b3dbd4f | ||
|
|
bf7b8ccce8 | ||
|
|
57b1895b5e | ||
|
|
8edf65186f | ||
|
|
13d781d2b1 | ||
|
|
7c1c99f5f9 | ||
|
|
0a02f43b8c | ||
|
|
d4e50d9560 | ||
|
|
5681e0bfdf | ||
|
|
55bfe4cad8 | ||
|
|
d726792be6 | ||
|
|
5c21451760 | ||
|
|
b3736ac13a | ||
|
|
a4899de956 | ||
|
|
e3ca70ba0d | ||
|
|
bdace1b1b7 | ||
|
|
567022a9b7 | ||
|
|
83262afd13 | ||
|
|
3ff838a2cc | ||
|
|
40b5c45ef6 | ||
|
|
c9ee55863f | ||
|
|
c622ff2b19 | ||
|
|
2b04c6a7dd |
10
.travis.yml
10
.travis.yml
@@ -1,3 +1,13 @@
|
||||
language: java
|
||||
jdk: oraclejdk7
|
||||
script: mvn install -DreleaseTesting
|
||||
env:
|
||||
global:
|
||||
secure: ZUzhWfpXJw/oAeDlUkDFkEJMT0T7kCN3d7ah8urkL2B0KFfKOqQagkbXkgvDa1SYud8VdcnoGa69LfkEr5IrdqW7R4bEYZAiN5swm4Z0iO8t53szVspm2f+O9jQ44O/sfOfpfLxWUUuhdc7Vbrszp+tSszxdPmssWL+f5a/mfWs=
|
||||
|
||||
before_install:
|
||||
- sudo apt-get install jq
|
||||
- wget -O ~/codacy-coverage-reporter-assembly-latest.jar $(curl https://api.github.com/repos/codacy/codacy-coverage-reporter/releases/latest | jq -r .assets[0].browser_download_url)
|
||||
|
||||
after_success:
|
||||
- java -cp ~/codacy-coverage-reporter-assembly-latest.jar com.codacy.CodacyCoverageReporter -l Java -r build-reporting/target/site/jacoco-aggregate/jacoco.xml
|
||||
|
||||
25
Dockerfile
25
Dockerfile
@@ -2,13 +2,28 @@ FROM java:8
|
||||
|
||||
MAINTAINER Timo Pagel <dependencycheckmaintainer@timo-pagel.de>
|
||||
|
||||
RUN wget -O /tmp/current.txt http://jeremylong.github.io/DependencyCheck/current.txt && current=$(cat /tmp/current.txt) && wget https://dl.bintray.com/jeremy-long/owasp/dependency-check-$current-release.zip && unzip dependency-check-$current-release.zip && mv dependency-check /usr/share/
|
||||
ENV user=dependencycheck
|
||||
ENV version_url=https://jeremylong.github.io/DependencyCheck/current.txt
|
||||
ENV download_url=https://dl.bintray.com/jeremy-long/owasp
|
||||
|
||||
RUN useradd -ms /bin/bash dockeruser && chown -R dockeruser:dockeruser /usr/share/dependency-check && mkdir /report && chown -R dockeruser:dockeruser /report
|
||||
USER dockeruser
|
||||
RUN wget -O /tmp/current.txt ${version_url} && \
|
||||
version=$(cat /tmp/current.txt) && \
|
||||
file="dependency-check-${version}-release.zip" && \
|
||||
wget "$download_url/$file" && \
|
||||
unzip ${file} && \
|
||||
rm ${file} && \
|
||||
mv dependency-check /usr/share/
|
||||
|
||||
VOLUME "/src /usr/share/dependency-check/data /report"
|
||||
RUN useradd -ms /bin/bash ${user} && \
|
||||
chown -R ${user}:${user} /usr/share/dependency-check && \
|
||||
mkdir /report && \
|
||||
chown -R ${user}:${user} /report
|
||||
|
||||
USER ${user}
|
||||
|
||||
VOLUME ["/src" "/usr/share/dependency-check/data" "/report"]
|
||||
|
||||
WORKDIR /report
|
||||
|
||||
ENTRYPOINT ["/usr/share/dependency-check/bin/dependency-check.sh", "--scan", "/src"]
|
||||
CMD ["--help"]
|
||||
ENTRYPOINT ["/usr/share/dependency-check/bin/dependency-check.sh"]
|
||||
|
||||
52
README.md
52
README.md
@@ -29,8 +29,8 @@ $ ./bin/dependency-check.sh --project Testing --out . --scan [path to jar files
|
||||
```
|
||||
On Windows
|
||||
```
|
||||
> bin/dependency-check.bat -h
|
||||
> bin/dependency-check.bat --project Testing --out . --scan [path to jar files to be scanned]
|
||||
> .\bin\dependency-check.bat -h
|
||||
> .\bin\dependency-check.bat --project Testing --out . --scan [path to jar files to be scanned]
|
||||
```
|
||||
On Mac with [Homebrew](http://brew.sh)
|
||||
```
|
||||
@@ -93,40 +93,46 @@ $ ./dependency-check-cli/target/release/bin/dependency-check.sh --project Testin
|
||||
On Windows
|
||||
```
|
||||
> mvn install
|
||||
> dependency-check-cli/target/release/bin/dependency-check.bat -h
|
||||
> dependency-check-cli/target/release/bin/dependency-check.bat --project Testing --out . --scan ./src/test/resources
|
||||
> .\dependency-check-cli\target\release\bin\dependency-check.bat -h
|
||||
> .\dependency-check-cli\target\release\bin\dependency-check.bat --project Testing --out . --scan ./src/test/resources
|
||||
```
|
||||
|
||||
Then load the resulting 'DependencyCheck-Report.html' into your favorite browser.
|
||||
|
||||
### Docker
|
||||
|
||||
In the following example it is assumed that the source to be checked is in the actual directory. A persistent data directory and a persistent report directory is used so that the container can be destroyed after running it to make sure that you use the newest version, always.
|
||||
In the following example it is assumed that the source to be checked is in the current working directory. Persistent data and report directories are used, allowing you to destroy the container after running.
|
||||
|
||||
```
|
||||
# After the first run, feel free to change the owner of the directories to the owner of the created files and the permissions to 744
|
||||
DATA_DIRECTORY=$HOME/OWASP-Dependency-Check/data
|
||||
REPORT_DIRECTORY=/$HOME/OWASP-Dependency-Check/reports
|
||||
#!/bin/sh
|
||||
|
||||
if [ ! -d $DATA_DIRECTORY ]; then
|
||||
echo "Initially creating persistent directories"
|
||||
mkdir -p $DATA_DIRECTORY
|
||||
chmod -R 777 $DATA_DIRECTORY
|
||||
OWASPDC_DIRECTORY=$HOME/OWASP-Dependency-Check
|
||||
DATA_DIRECTORY="$OWASPDC_DIRECTORY/data"
|
||||
REPORT_DIRECTORY="$OWASPDC_DIRECTORY/reports"
|
||||
|
||||
mkdir -p $REPORT_DIRECTORY
|
||||
chmod -R 777 $REPORT_DIRECTORY
|
||||
if [ ! -d "$DATA_DIRECTORY" ]; then
|
||||
echo "Initially creating persistent directories"
|
||||
mkdir -p "$DATA_DIRECTORY"
|
||||
chmod -R 777 "$DATA_DIRECTORY"
|
||||
|
||||
mkdir -p "$REPORT_DIRECTORY"
|
||||
chmod -R 777 "$REPORT_DIRECTORY"
|
||||
fi
|
||||
|
||||
docker pull owasp/dependency-check # Make sure it is the actual version
|
||||
# Make sure we are using the latest version
|
||||
docker pull owasp/dependency-check
|
||||
|
||||
docker run --rm \
|
||||
--volume $(pwd):/src \
|
||||
--volume $DATA_DIRECTORY:/usr/share/dependency-check/data \
|
||||
--volume $REPORT_DIRECTORY:/report \
|
||||
--name dependency-check \
|
||||
dc \
|
||||
--suppression "/src/security/dependency-check-suppression.xml"\
|
||||
--format "ALL" \
|
||||
--project "My OWASP Dependency Check Project" \
|
||||
--volume $(pwd):/src \
|
||||
--volume "$DATA_DIRECTORY":/usr/share/dependency-check/data \
|
||||
--volume "$REPORT_DIRECTORY":/report \
|
||||
owasp/dependency-check \
|
||||
--scan /src \
|
||||
--format "ALL" \
|
||||
--project "My OWASP Dependency Check Project"
|
||||
# Use suppression like this: (/src == $pwd)
|
||||
# --suppression "/src/security/dependency-check-suppression.xml"
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
80
build-reporting/pom.xml
Normal file
80
build-reporting/pom.xml
Normal file
@@ -0,0 +1,80 @@
|
||||
<!--
|
||||
This file is part of dependency-check build-reporting.
|
||||
|
||||
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) 2017 - Jeremy Long. All Rights Reserved.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.4.6-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>build-reporting</artifactId>
|
||||
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
|
||||
<distributionManagement>
|
||||
<site>
|
||||
<id>github-pages-site</id>
|
||||
<name>Deployment through GitHub's site deployment plugin</name>
|
||||
<url>${basedir}/../target/site/${project.version}/build-reporting</url>
|
||||
</site>
|
||||
</distributionManagement>
|
||||
<!-- end copy -->
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-utils</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-ant</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-cli</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-maven</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>report-aggregate</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>report-aggregate</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
5
build-reporting/src/site/markdown/index.md
Normal file
5
build-reporting/src/site/markdown/index.md
Normal file
@@ -0,0 +1,5 @@
|
||||
About
|
||||
=====
|
||||
OWASP dependency-check build reporting is used to aggregate jacoco test coverage results
|
||||
so that they can be posted to [Codacy](https://www.codacy.com/app/OWASP_Reviews/DependencyCheck/dashboard)
|
||||
to track code coverage.
|
||||
32
build-reporting/src/site/site.xml
Normal file
32
build-reporting/src/site/site.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!--
|
||||
This file is part of dependency-check build reporting.
|
||||
|
||||
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) 2017 Jeremy Long. All Rights Reserved.
|
||||
-->
|
||||
<project name="dependency-check-build-reporting">
|
||||
<bannerLeft>
|
||||
<name>OWASP dependency-check build reporting</name>
|
||||
<alt>OWASP dependency-check build reporting</alt>
|
||||
<src>../images/dc.svg</src>
|
||||
</bannerLeft>
|
||||
<body>
|
||||
<breadcrumbs>
|
||||
<item name="dependency-check" href="../index.html"/>
|
||||
</breadcrumbs>
|
||||
<menu ref="Project Documentation" />
|
||||
<menu ref="reports" />
|
||||
</body>
|
||||
</project>
|
||||
@@ -223,48 +223,6 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<check>
|
||||
<branchRate>85</branchRate>
|
||||
<lineRate>85</lineRate>
|
||||
<haltOnFailure>false</haltOnFailure>
|
||||
<totalBranchRate>85</totalBranchRate>
|
||||
<totalLineRate>85</totalLineRate>
|
||||
<packageLineRate>85</packageLineRate>
|
||||
<packageBranchRate>85</packageBranchRate>
|
||||
<regexes>
|
||||
<regex>
|
||||
<pattern>.*\$.*</pattern>
|
||||
<branchRate>0</branchRate>
|
||||
<lineRate>0</lineRate>
|
||||
</regex>
|
||||
</regexes>
|
||||
</check>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>-Dfile.encoding=UTF-8</argLine>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>data.directory</name>
|
||||
<value>${project.build.directory}/dependency-check-data</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<reporting>
|
||||
|
||||
@@ -146,7 +146,7 @@ public class Check extends Update {
|
||||
private boolean updateOnly = false;
|
||||
|
||||
/**
|
||||
* The report format to be generated (HTML, XML, VULN, ALL). Default is
|
||||
* The report format to be generated (HTML, XML, VULN, CSV, JSON, ALL). Default is
|
||||
* HTML.
|
||||
*/
|
||||
private String reportFormat = "HTML";
|
||||
@@ -940,16 +940,7 @@ public class Check extends Update {
|
||||
throw new BuildException(ex);
|
||||
}
|
||||
}
|
||||
DatabaseProperties prop = null;
|
||||
try (CveDB cve = CveDB.getInstance()) {
|
||||
prop = cve.getDatabaseProperties();
|
||||
} catch (DatabaseException ex) {
|
||||
//TODO shouldn't this be a fatal exception
|
||||
log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG);
|
||||
}
|
||||
|
||||
final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop);
|
||||
reporter.generateReports(reportOutputDirectory, reportFormat);
|
||||
engine.writeReports(getProjectName(),new File(reportOutputDirectory), reportFormat);
|
||||
|
||||
if (this.failBuildOnCVSS <= 10) {
|
||||
checkForFailure(engine.getDependencies());
|
||||
@@ -1102,7 +1093,7 @@ public class Check extends Update {
|
||||
}
|
||||
|
||||
/**
|
||||
* An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN",
|
||||
* An enumeration of supported report formats: "ALL", "HTML", "XML", "CSV", "JSON", "VULN",
|
||||
* etc..
|
||||
*/
|
||||
public static class ReportFormats extends EnumeratedAttribute {
|
||||
|
||||
@@ -36,11 +36,11 @@ cveValidForHours | Sets the number of hours to wait before checking for new
|
||||
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
|
||||
failOnError | Whether the build should fail if there is an error executing the dependency-check analysis | true
|
||||
projectName | The name of the project being scanned. | Dependency-Check
|
||||
reportFormat | 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
|
||||
reportFormat | The report format to be generated (HTML, XML, CSV, JSON, VULN, ALL). This configuration option has no affect if using this within the Site plugin unless the externalReport is set to true. | HTML
|
||||
reportOutputDirectory | 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 | The file path to the XML suppression file \- used to suppress [false positives](../general/suppression.html) |
|
||||
hintsFile | The file path to the XML hints file \- used to resolve [false negatives](../general/hints.html) |
|
||||
proxyServer | The Proxy Server; see the [proxy configuration](../data/proxy.html) page for more information. |
|
||||
hintsFile | The file path to the XML hints file \- used to resolve [false negatives](../general/hints.html) |
|
||||
proxyServer | The Proxy Server; see the [proxy configuration](../data/proxy.html) page for more information. |
|
||||
proxyPort | The Proxy Port. |
|
||||
proxyUsername | Defines the proxy user name. |
|
||||
proxyPassword | Defines the proxy password. |
|
||||
|
||||
@@ -69,62 +69,6 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<!--instrumentation>
|
||||
<ignoreTrivial>true</ignoreTrivial>
|
||||
</instrumentation-->
|
||||
<check>
|
||||
<branchRate>85</branchRate>
|
||||
<lineRate>85</lineRate>
|
||||
<haltOnFailure>false</haltOnFailure>
|
||||
<totalBranchRate>85</totalBranchRate>
|
||||
<totalLineRate>85</totalLineRate>
|
||||
<packageLineRate>85</packageLineRate>
|
||||
<packageBranchRate>85</packageBranchRate>
|
||||
<regexes>
|
||||
<regex>
|
||||
<pattern>.*\$.*</pattern>
|
||||
<branchRate>0</branchRate>
|
||||
<lineRate>0</lineRate>
|
||||
</regex>
|
||||
<regex>
|
||||
<pattern>org.owasp.dependencycheck.App</pattern>
|
||||
<branchRate>0</branchRate>
|
||||
<lineRate>0</lineRate>
|
||||
</regex>
|
||||
</regexes>
|
||||
</check>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>-Dfile.encoding=UTF-8</argLine>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>cpe</name>
|
||||
<value>data/cpe</value>
|
||||
<workingDirectory>target</workingDirectory>
|
||||
</property>
|
||||
<property>
|
||||
<name>cve</name>
|
||||
<value>data/cpe</value>
|
||||
<workingDirectory>target</workingDirectory>
|
||||
</property>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>appassembler-maven-plugin</artifactId>
|
||||
|
||||
@@ -281,18 +281,9 @@ public class App {
|
||||
}
|
||||
exCol = ex;
|
||||
}
|
||||
final List<Dependency> dependencies = engine.getDependencies();
|
||||
DatabaseProperties prop = null;
|
||||
try (CveDB cve = CveDB.getInstance()) {
|
||||
prop = cve.getDatabaseProperties();
|
||||
} catch (DatabaseException ex) {
|
||||
//TODO shouldn't this be a fatal exception
|
||||
LOGGER.debug("Unable to retrieve DB Properties", ex);
|
||||
}
|
||||
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop);
|
||||
|
||||
try {
|
||||
report.generateReports(reportDirectory, outputFormat);
|
||||
engine.writeReports(applicationName, new File(reportDirectory), outputFormat);
|
||||
} catch (ReportException ex) {
|
||||
if (exCol != null) {
|
||||
exCol.addException(ex);
|
||||
@@ -306,7 +297,7 @@ public class App {
|
||||
}
|
||||
|
||||
//Set the exit code based on whether we found a high enough vulnerability
|
||||
for (Dependency dep : dependencies) {
|
||||
for (Dependency dep : engine.getDependencies()) {
|
||||
if (!dep.getVulnerabilities().isEmpty()) {
|
||||
for (Vulnerability vuln : dep.getVulnerabilities()) {
|
||||
LOGGER.debug("VULNERABILITY FOUND " + dep.getDisplayFileName());
|
||||
@@ -316,7 +307,6 @@ public class App {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retCode;
|
||||
} finally {
|
||||
if (engine != null) {
|
||||
@@ -353,8 +343,7 @@ public class App {
|
||||
* @throws InvalidSettingException thrown when a user defined properties
|
||||
* file is unable to be loaded.
|
||||
*/
|
||||
private void populateSettings(CliParser cli) throws InvalidSettingException {
|
||||
final boolean autoUpdate = cli.isAutoUpdate();
|
||||
protected void populateSettings(CliParser cli) throws InvalidSettingException {
|
||||
final String connectionTimeout = cli.getConnectionTimeout();
|
||||
final String proxyServer = cli.getProxyServer();
|
||||
final String proxyPort = cli.getProxyPort();
|
||||
@@ -377,7 +366,8 @@ public class App {
|
||||
final String cveBase12 = cli.getBaseCve12Url();
|
||||
final String cveBase20 = cli.getBaseCve20Url();
|
||||
final Integer cveValidForHours = cli.getCveValidForHours();
|
||||
final boolean experimentalEnabled = cli.isExperimentalEnabled();
|
||||
final Boolean autoUpdate = cli.isAutoUpdate();
|
||||
final Boolean experimentalEnabled = cli.isExperimentalEnabled();
|
||||
|
||||
if (propertiesFile != null) {
|
||||
try {
|
||||
@@ -390,7 +380,7 @@ public class App {
|
||||
}
|
||||
// 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
|
||||
// on the command line. This is true of other boolean values set below not using the setBooleanIfNotNull.
|
||||
final boolean nexusUsesProxy = cli.isNexusUsesProxy();
|
||||
if (dataDirectory != null) {
|
||||
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
|
||||
@@ -404,7 +394,7 @@ public class App {
|
||||
final File dataDir = new File(base, sub);
|
||||
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
|
||||
}
|
||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
|
||||
Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate);
|
||||
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_SERVER, proxyServer);
|
||||
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PORT, proxyPort);
|
||||
Settings.setStringIfNotEmpty(Settings.KEYS.PROXY_USERNAME, proxyUser);
|
||||
@@ -415,7 +405,8 @@ public class App {
|
||||
Settings.setIntIfNotNull(Settings.KEYS.CVE_CHECK_VALID_FOR_HOURS, cveValidForHours);
|
||||
|
||||
//File Type Analyzer Settings
|
||||
Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, experimentalEnabled);
|
||||
Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, experimentalEnabled);
|
||||
|
||||
Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !cli.isJarDisabled());
|
||||
Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !cli.isArchiveDisabled());
|
||||
Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !cli.isPythonDistributionDisabled());
|
||||
|
||||
@@ -120,7 +120,7 @@ public final class CliParser {
|
||||
Format.valueOf(format);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
final String msg = String.format("An invalid 'format' of '%s' was specified. "
|
||||
+ "Supported output formats are XML, HTML, VULN, or ALL", format);
|
||||
+ "Supported output formats are HTML, XML, CSV, JSON, VULN, or ALL", format);
|
||||
throw new ParseException(msg);
|
||||
}
|
||||
}
|
||||
@@ -262,7 +262,7 @@ public final class CliParser {
|
||||
.build();
|
||||
|
||||
final Option outputFormat = Option.builder(ARGUMENT.OUTPUT_FORMAT_SHORT).argName("format").hasArg().longOpt(ARGUMENT.OUTPUT_FORMAT)
|
||||
.desc("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.")
|
||||
.desc("The output format to write to (XML, JSON, HTML, VULN, ALL). The default is HTML.")
|
||||
.build();
|
||||
|
||||
final Option verboseLog = Option.builder(ARGUMENT.VERBOSE_LOG_SHORT).argName("file").hasArg().longOpt(ARGUMENT.VERBOSE_LOG)
|
||||
@@ -567,6 +567,32 @@ public final class CliParser {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to determine if one of the disable options has been set.
|
||||
* If not set, this method will check the currently configured settings for
|
||||
* the current value to return.
|
||||
*
|
||||
* Example given `--disableArchive` on the command line would cause this
|
||||
* method to return true for the disable archive setting.
|
||||
*
|
||||
* @param argument the command line argument
|
||||
* @param setting the corresponding settings key
|
||||
* @return true if the disable option was set, if not set the currently
|
||||
* configured value will be returned
|
||||
*/
|
||||
private boolean hasDisableOption(String argument, String setting) {
|
||||
if (line == null || !line.hasOption(argument)) {
|
||||
try {
|
||||
return !Settings.getBoolean(setting);
|
||||
} catch (InvalidSettingException ise) {
|
||||
LOGGER.warn("Invalid property setting '{}' defaulting to false", setting);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the disableJar command line argument was specified.
|
||||
*
|
||||
@@ -574,7 +600,7 @@ public final class CliParser {
|
||||
* otherwise false
|
||||
*/
|
||||
public boolean isJarDisabled() {
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_JAR, Settings.KEYS.ANALYZER_JAR_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -584,7 +610,7 @@ public final class CliParser {
|
||||
* otherwise false
|
||||
*/
|
||||
public boolean isArchiveDisabled() {
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_ARCHIVE, Settings.KEYS.ANALYZER_ARCHIVE_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -594,7 +620,7 @@ public final class CliParser {
|
||||
* otherwise false
|
||||
*/
|
||||
public boolean isNuspecDisabled() {
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_NUSPEC, Settings.KEYS.ANALYZER_NUSPEC_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -604,7 +630,7 @@ public final class CliParser {
|
||||
* otherwise false
|
||||
*/
|
||||
public boolean isAssemblyDisabled() {
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_ASSEMBLY, Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -615,7 +641,7 @@ public final class CliParser {
|
||||
* specified; otherwise false
|
||||
*/
|
||||
public boolean isBundleAuditDisabled() {
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_BUNDLE_AUDIT);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_BUNDLE_AUDIT, Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -625,7 +651,7 @@ public final class CliParser {
|
||||
* otherwise false
|
||||
*/
|
||||
public boolean isPythonDistributionDisabled() {
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_DIST);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_PY_DIST, Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -635,7 +661,7 @@ public final class CliParser {
|
||||
* otherwise false
|
||||
*/
|
||||
public boolean isPythonPackageDisabled() {
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_PY_PKG, Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -645,7 +671,7 @@ public final class CliParser {
|
||||
* argument was specified; otherwise false
|
||||
*/
|
||||
public boolean isRubyGemspecDisabled() {
|
||||
return (null != line) && line.hasOption(ARGUMENT.DISABLE_RUBYGEMS);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_RUBYGEMS, Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -655,7 +681,7 @@ public final class CliParser {
|
||||
* otherwise false
|
||||
*/
|
||||
public boolean isCmakeDisabled() {
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_CMAKE);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_CMAKE, Settings.KEYS.ANALYZER_CMAKE_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -665,7 +691,7 @@ public final class CliParser {
|
||||
* otherwise false
|
||||
*/
|
||||
public boolean isAutoconfDisabled() {
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_AUTOCONF);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_AUTOCONF, Settings.KEYS.ANALYZER_AUTOCONF_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -675,7 +701,7 @@ public final class CliParser {
|
||||
* otherwise false
|
||||
*/
|
||||
public boolean isComposerDisabled() {
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_COMPOSER);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_COMPOSER, Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -685,7 +711,7 @@ public final class CliParser {
|
||||
* otherwise false
|
||||
*/
|
||||
public boolean isNexusDisabled() {
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_NEXUS, Settings.KEYS.ANALYZER_NEXUS_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -695,7 +721,7 @@ public final class CliParser {
|
||||
* otherwise false
|
||||
*/
|
||||
public boolean isOpenSSLDisabled() {
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_OPENSSL);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_OPENSSL, Settings.KEYS.ANALYZER_OPENSSL_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -705,7 +731,7 @@ public final class CliParser {
|
||||
* otherwise false
|
||||
*/
|
||||
public boolean isNodeJsDisabled() {
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_NODE_JS);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_NODE_JS, Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -716,7 +742,7 @@ public final class CliParser {
|
||||
* specified; otherwise false
|
||||
*/
|
||||
public boolean isCocoapodsAnalyzerDisabled() {
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_COCOAPODS);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_COCOAPODS, Settings.KEYS.ANALYZER_COCOAPODS_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -727,7 +753,7 @@ public final class CliParser {
|
||||
* argument was specified; otherwise false
|
||||
*/
|
||||
public boolean isSwiftPackageAnalyzerDisabled() {
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_SWIFT);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_SWIFT, Settings.KEYS.ANALYZER_SWIFT_PACKAGE_MANAGER_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -737,7 +763,7 @@ public final class CliParser {
|
||||
* otherwise false
|
||||
*/
|
||||
public boolean isCentralDisabled() {
|
||||
return (line != null) && line.hasOption(ARGUMENT.DISABLE_CENTRAL);
|
||||
return hasDisableOption(ARGUMENT.DISABLE_CENTRAL, Settings.KEYS.ANALYZER_CENTRAL_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1029,10 +1055,10 @@ public final class CliParser {
|
||||
* disabled via the command line this will return false.
|
||||
*
|
||||
* @return <code>true</code> if auto-update is allowed; otherwise
|
||||
* <code>false</code>
|
||||
* <code>null</code>
|
||||
*/
|
||||
public boolean isAutoUpdate() {
|
||||
return line != null && !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE);
|
||||
public Boolean isAutoUpdate() {
|
||||
return (line != null && line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE)) ? false : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1134,10 +1160,10 @@ public final class CliParser {
|
||||
/**
|
||||
* Returns true if the experimental analyzers are enabled.
|
||||
*
|
||||
* @return true if the experimental analyzers are enabled; otherwise false
|
||||
* @return true if the experimental analyzers are enabled; otherwise null
|
||||
*/
|
||||
public boolean isExperimentalEnabled() {
|
||||
return line.hasOption(ARGUMENT.EXPERIMENTAL);
|
||||
public Boolean isExperimentalEnabled() {
|
||||
return (line != null && line.hasOption(ARGUMENT.EXPERIMENTAL)) ? true : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,22 +4,22 @@ Command Line Arguments
|
||||
The following table lists the command line arguments:
|
||||
|
||||
Short | Argument Name | Parameter | Description | Requirement
|
||||
-------|-----------------------|-----------------|-------------|------------
|
||||
| \-\-project | \<name\> | The name of the project being scanned. | Required
|
||||
\-s | \-\-scan | \<path\> | The path to scan \- this option can be specified multiple times. It is also possible to specify Ant style paths (e.g. directory/**/*.jar). | Required
|
||||
| \-\-exclude | \<pattern\> | The path patterns to exclude from the scan \- this option can be specified multiple times. This accepts Ant style path patterns (e.g. **/exclude/**). | Optional
|
||||
| \-\-symLink | \<depth\> | The depth that symbolic links will be followed; the default is 0 meaning symbolic links will not be followed. | Optional
|
||||
\-o | \-\-out | \<path\> | The folder to write reports to. This defaults to the current directory. If the format is not set to ALL one could specify a specific file name. | Optional
|
||||
\-f | \-\-format | \<format\> | The output format to write to (XML, HTML, VULN, ALL). The default is HTML. | Required
|
||||
| \-\-failOnCvss | \<score\> | If the score set between 0 and 10 the exit code from dependency-check will indicate if a vulnerability with a CVSS score equal to or higher was identified. | Optional
|
||||
\-l | \-\-log | \<file\> | The file path to write verbose logging information. | Optional
|
||||
\-n | \-\-noupdate | | Disables the automatic updating of the CPE data. | Optional
|
||||
| \-\-suppression | \<file\> | The file path to the suppression XML file; used to suppress [false positives](../general/suppression.html). | Optional
|
||||
\-h | \-\-help | | Print the help message. | Optional
|
||||
| \-\-advancedHelp | | Print the advanced help message. | Optional
|
||||
\-v | \-\-version | | Print the version information. | Optional
|
||||
| \-\-cveValidForHours | \<hours\> | The number of hours to wait before checking for new updates from the NVD. The default is 4 hours. | Optional
|
||||
| \-\-experimental | | Enable the [experimental analyzers](../analyzers/index.html). If not set the analyzers marked as experimental below will not be loaded or used. | Optional
|
||||
-------|------------------------|-----------------|-------------|------------
|
||||
| \-\-project | \<name\> | The name of the project being scanned. | Required
|
||||
\-s | \-\-scan | \<path\> | The path to scan \- this option can be specified multiple times. It is also possible to specify Ant style paths (e.g. directory/**/*.jar). | Required
|
||||
| \-\-exclude | \<pattern\> | The path patterns to exclude from the scan \- this option can be specified multiple times. This accepts Ant style path patterns (e.g. **/exclude/**). | Optional
|
||||
| \-\-symLink | \<depth\> | The depth that symbolic links will be followed; the default is 0 meaning symbolic links will not be followed. | Optional
|
||||
\-o | \-\-out | \<path\> | The folder to write reports to. This defaults to the current directory. If the format is not set to ALL one could specify a specific file name. | Optional
|
||||
\-f | \-\-format | \<format\> | The output format to write to (XML, HTML, CSV, JSON, VULN, ALL). The default is HTML. | Required
|
||||
| \-\-failOnCvss | \<score\> | If the score set between 0 and 10 the exit code from dependency-check will indicate if a vulnerability with a CVSS score equal to or higher was identified. | Optional
|
||||
\-l | \-\-log | \<file\> | The file path to write verbose logging information. | Optional
|
||||
\-n | \-\-noupdate | | Disables the automatic updating of the CPE data. | Optional
|
||||
| \-\-suppression | \<file\> | The file path to the suppression XML file; used to suppress [false positives](../general/suppression.html). | Optional
|
||||
\-h | \-\-help | | Print the help message. | Optional
|
||||
| \-\-advancedHelp | | Print the advanced help message. | Optional
|
||||
\-v | \-\-version | | Print the version information. | Optional
|
||||
| \-\-cveValidForHours | \<hours\> | The number of hours to wait before checking for new updates from the NVD. The default is 4 hours. | Optional
|
||||
| \-\-enableExperimental | | Enable the [experimental analyzers](../analyzers/index.html). If not set the analyzers marked as experimental below will not be loaded or used. | Optional
|
||||
|
||||
Advanced Options
|
||||
================
|
||||
|
||||
@@ -13,18 +13,28 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2015 The OWASP Foundatio. All Rights Reserved.
|
||||
* Copyright (c) 2017 The OWASP Foundatio. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.commons.cli.UnrecognizedOptionException;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeremy
|
||||
*/
|
||||
public class AppTest {
|
||||
|
||||
/**
|
||||
* Test of ensureCanonicalPath method, of class App.
|
||||
*/
|
||||
@@ -35,17 +45,83 @@ public class AppTest {
|
||||
String result = instance.ensureCanonicalPath(file);
|
||||
assertFalse(result.contains(".."));
|
||||
assertTrue(result.endsWith("*.jar"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of ensureCanonicalPath method, of class App.
|
||||
*/
|
||||
@Test
|
||||
public void testEnsureCanonicalPath2() {
|
||||
String file = "../some/skip/../path/file.txt";
|
||||
App instance = new App();
|
||||
file = "../some/skip/../path/file.txt";
|
||||
String expResult = "/some/path/file.txt";
|
||||
String result = instance.ensureCanonicalPath(file);
|
||||
result = instance.ensureCanonicalPath(file);
|
||||
assertTrue("result=" + result, result.endsWith(expResult));
|
||||
}
|
||||
|
||||
@Test(expected = UnrecognizedOptionException.class)
|
||||
public void testPopulateSettingsException() throws FileNotFoundException, ParseException, InvalidSettingException, URISyntaxException {
|
||||
String[] args = {"-invalidPROPERTY"};
|
||||
assertTrue(testBooleanProperties(args, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPopulateSettings() throws FileNotFoundException, ParseException, InvalidSettingException, URISyntaxException {
|
||||
File prop = new File(this.getClass().getClassLoader().getResource("sample.properties").toURI().getPath());
|
||||
String[] args = {"-P", prop.getAbsolutePath()};
|
||||
Map<String, Boolean> expected = new HashMap<>();
|
||||
expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.FALSE);
|
||||
expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.TRUE);
|
||||
|
||||
assertTrue(testBooleanProperties(args, expected));
|
||||
|
||||
String[] args2 = {"-n"};
|
||||
expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.FALSE);
|
||||
expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.TRUE);
|
||||
assertTrue(testBooleanProperties(args2, expected));
|
||||
|
||||
String[] args3 = {"-h"};
|
||||
expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.TRUE);
|
||||
expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.TRUE);
|
||||
assertTrue(testBooleanProperties(args3, expected));
|
||||
|
||||
String[] args4 = {"--disableArchive"};
|
||||
expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.TRUE);
|
||||
expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.FALSE);
|
||||
assertTrue(testBooleanProperties(args4, expected));
|
||||
|
||||
String[] args5 = {"-P", prop.getAbsolutePath(), "--disableArchive"};
|
||||
expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.FALSE);
|
||||
expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.FALSE);
|
||||
assertTrue(testBooleanProperties(args5, expected));
|
||||
|
||||
prop = new File(this.getClass().getClassLoader().getResource("sample2.properties").toURI().getPath());
|
||||
String[] args6 = {"-P", prop.getAbsolutePath(), "--disableArchive"};
|
||||
expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.TRUE);
|
||||
expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.FALSE);
|
||||
assertTrue(testBooleanProperties(args6, expected));
|
||||
|
||||
String[] args7 = {"-P", prop.getAbsolutePath(), "--noupdate"};
|
||||
expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.FALSE);
|
||||
expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.FALSE);
|
||||
assertTrue(testBooleanProperties(args7, expected));
|
||||
|
||||
String[] args8 = {"-P", prop.getAbsolutePath(), "--noupdate", "--disableArchive"};
|
||||
expected.put(Settings.KEYS.AUTO_UPDATE, Boolean.FALSE);
|
||||
expected.put(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, Boolean.FALSE);
|
||||
assertTrue(testBooleanProperties(args8, expected));
|
||||
|
||||
|
||||
}
|
||||
|
||||
private boolean testBooleanProperties(String[] args, Map<String, Boolean> expected) throws URISyntaxException, FileNotFoundException, ParseException, InvalidSettingException {
|
||||
Settings.initialize();
|
||||
try {
|
||||
final CliParser cli = new CliParser();
|
||||
cli.parse(args);
|
||||
App instance = new App();
|
||||
instance.populateSettings(cli);
|
||||
boolean results = true;
|
||||
for (Map.Entry<String, Boolean> entry : expected.entrySet()) {
|
||||
results &= Settings.getBoolean(entry.getKey()) == entry.getValue();
|
||||
}
|
||||
|
||||
return results;
|
||||
} finally {
|
||||
Settings.cleanup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
33
dependency-check-cli/src/test/resources/sample.properties
Normal file
33
dependency-check-cli/src/test/resources/sample.properties
Normal file
@@ -0,0 +1,33 @@
|
||||
autoupdate=false
|
||||
|
||||
analyzer.experimental.enabled=false
|
||||
analyzer.jar.enabled=true
|
||||
analyzer.archive.enabled=true
|
||||
analyzer.node.package.enabled=true
|
||||
analyzer.composer.lock.enabled=true
|
||||
analyzer.python.distribution.enabled=true
|
||||
analyzer.python.package.enabled=true
|
||||
analyzer.ruby.gemspec.enabled=true
|
||||
analyzer.autoconf.enabled=true
|
||||
analyzer.cmake.enabled=true
|
||||
analyzer.assembly.enabled=true
|
||||
analyzer.nuspec.enabled=true
|
||||
analyzer.openssl.enabled=true
|
||||
analyzer.central.enabled=true
|
||||
analyzer.nexus.enabled=false
|
||||
analyzer.cocoapods.enabled=true
|
||||
analyzer.swift.package.manager.enabled=true
|
||||
#whether the nexus analyzer uses the proxy
|
||||
analyzer.nexus.proxy=true
|
||||
analyzer.cpe.enabled=true
|
||||
analyzer.cpesuppression.enabled=true
|
||||
analyzer.dependencybundling.enabled=true
|
||||
analyzer.dependencymerging.enabled=true
|
||||
analyzer.falsepositive.enabled=true
|
||||
analyzer.filename.enabled=true
|
||||
analyzer.hint.enabled=true
|
||||
analyzer.nvdcve.enabled=true
|
||||
analyzer.vulnerabilitysuppression.enabled=true
|
||||
updater.nvdcve.enabled=true
|
||||
updater.versioncheck.enabled=true
|
||||
analyzer.versionfilter.enabled=true
|
||||
33
dependency-check-cli/src/test/resources/sample2.properties
Normal file
33
dependency-check-cli/src/test/resources/sample2.properties
Normal file
@@ -0,0 +1,33 @@
|
||||
autoupdate=true
|
||||
|
||||
analyzer.experimental.enabled=true
|
||||
analyzer.jar.enabled=false
|
||||
analyzer.archive.enabled=false
|
||||
analyzer.node.package.enabled=false
|
||||
analyzer.composer.lock.enabled=false
|
||||
analyzer.python.distribution.enabled=false
|
||||
analyzer.python.package.enabled=false
|
||||
analyzer.ruby.gemspec.enabled=false
|
||||
analyzer.autoconf.enabled=false
|
||||
analyzer.cmake.enabled=false
|
||||
analyzer.assembly.enabled=false
|
||||
analyzer.nuspec.enabled=false
|
||||
analyzer.openssl.enabled=false
|
||||
analyzer.central.enabled=false
|
||||
analyzer.nexus.enabled=true
|
||||
analyzer.cocoapods.enabled=false
|
||||
analyzer.swift.package.manager.enabled=false
|
||||
#whether the nexus analyzer uses the proxy
|
||||
analyzer.nexus.proxy=false
|
||||
analyzer.cpe.enabled=false
|
||||
analyzer.cpesuppression.enabled=false
|
||||
analyzer.dependencybundling.enabled=false
|
||||
analyzer.dependencymerging.enabled=false
|
||||
analyzer.falsepositive.enabled=false
|
||||
analyzer.filename.enabled=false
|
||||
analyzer.hint.enabled=false
|
||||
analyzer.nvdcve.enabled=false
|
||||
analyzer.vulnerabilitysuppression.enabled=false
|
||||
updater.nvdcve.enabled=false
|
||||
updater.versioncheck.enabled=false
|
||||
analyzer.versionfilter.enabled=false
|
||||
@@ -121,93 +121,6 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<instrumentation>
|
||||
<!--ignoreTrivial>true</ignoreTrivial-->
|
||||
<ignores>
|
||||
<ignore>.*\$KEYS\.class</ignore>
|
||||
<ignore>.*\$Element\.class</ignore>
|
||||
</ignores>
|
||||
<excludes>
|
||||
<exclude>.*\$KEYS\.class</exclude>
|
||||
<exclude>.*\$Element\.class</exclude>
|
||||
</excludes>
|
||||
</instrumentation>
|
||||
<check>
|
||||
<branchRate>85</branchRate>
|
||||
<lineRate>85</lineRate>
|
||||
<haltOnFailure>false</haltOnFailure>
|
||||
<totalBranchRate>85</totalBranchRate>
|
||||
<totalLineRate>85</totalLineRate>
|
||||
<packageLineRate>85</packageLineRate>
|
||||
<packageBranchRate>85</packageBranchRate>
|
||||
<regexes>
|
||||
<regex>
|
||||
<pattern>.*\$.*</pattern>
|
||||
<branchRate>0</branchRate>
|
||||
<lineRate>0</lineRate>
|
||||
</regex>
|
||||
<regex>
|
||||
<pattern>org.owasp.dependencycheck.data.cpe.Fields</pattern>
|
||||
<branchRate>0</branchRate>
|
||||
<lineRate>0</lineRate>
|
||||
</regex>
|
||||
<regex>
|
||||
<pattern>org.owasp.dependencycheck.App</pattern>
|
||||
<branchRate>0</branchRate>
|
||||
<lineRate>0</lineRate>
|
||||
</regex>
|
||||
</regexes>
|
||||
</check>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>-Dfile.encoding=UTF-8</argLine>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>data.directory</name>
|
||||
<value>${project.build.directory}/data</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>temp.directory</name>
|
||||
<value>${project.build.directory}/temp</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
<excludes>
|
||||
<exclude>**/*IntegrationTest.java</exclude>
|
||||
<exclude>**/*MySQLTest.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>data.directory</name>
|
||||
<value>${project.build.directory}/data</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>temp.directory</name>
|
||||
<value>${project.build.directory}/temp</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<reporting>
|
||||
@@ -340,6 +253,10 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
<groupId>com.sun.mail</groupId>
|
||||
<artifactId>mailapi</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
<!-- The following dependencies are only used during testing -->
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.scm</groupId>
|
||||
@@ -470,6 +387,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
<scope>test</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<profiles>
|
||||
<profile>
|
||||
@@ -481,13 +399,6 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
@@ -507,7 +418,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
</property>
|
||||
</systemProperties>
|
||||
<includes>
|
||||
<include>**/*MySQLTest.java</include>
|
||||
<include>**/*MySqlIT.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
<executions>
|
||||
@@ -538,13 +449,6 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
@@ -564,7 +468,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
</property>
|
||||
</systemProperties>
|
||||
<includes>
|
||||
<include>**/*MySQLTest.java</include>
|
||||
<include>**/*MySqlIT.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
<executions>
|
||||
@@ -672,13 +576,6 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
<scope>test</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.3.1</version>
|
||||
<scope>test</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.gerrit</groupId>
|
||||
<artifactId>gerrit-extension-api</artifactId>
|
||||
|
||||
@@ -54,6 +54,9 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
|
||||
import org.owasp.dependencycheck.exception.ReportException;
|
||||
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
||||
|
||||
/**
|
||||
* Scans files, directories, etc. for Dependencies. Analyzers are loaded and
|
||||
@@ -796,4 +799,42 @@ public class Engine implements FileFilter {
|
||||
exceptions.add(throwable);
|
||||
throw new ExceptionCollection(message, exceptions, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the report to the given output directory.
|
||||
*
|
||||
* @param applicationName the name of the application/project
|
||||
* @param groupId the Maven groupId
|
||||
* @param artifactId the Maven artifactId
|
||||
* @param version the Maven version
|
||||
* @param outputDir the path to the output directory (can include the full
|
||||
* file name if the format is not ALL)
|
||||
* @param format the report format (ALL, HTML, CSV, JSON, etc.)
|
||||
* @throws ReportException thrown if there is an error generating the report
|
||||
*/
|
||||
public void writeReports(String applicationName, String groupId, String artifactId,
|
||||
String version, File outputDir, String format) throws ReportException {
|
||||
|
||||
DatabaseProperties prop = database.getDatabaseProperties();
|
||||
final ReportGenerator r = new ReportGenerator(applicationName, groupId, artifactId, version, dependencies, getAnalyzers(), prop);
|
||||
try {
|
||||
r.write(outputDir.getAbsolutePath(), format);
|
||||
} catch (ReportException ex) {
|
||||
final String msg = String.format("Error generating the report for %s", applicationName);
|
||||
throw new ReportException(msg, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the report to the given output directory.
|
||||
*
|
||||
* @param applicationName the name of the application/project
|
||||
* @param outputDir the path to the output directory (can include the full
|
||||
* file name if the format is not ALL)
|
||||
* @param format the report format (ALL, HTML, CSV, JSON, etc.)
|
||||
* @throws ReportException thrown if there is an error generating the report
|
||||
*/
|
||||
public void writeReports(String applicationName, File outputDir, String format) throws ReportException {
|
||||
writeReports(applicationName, null, null, null, outputDir, format);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -840,21 +840,15 @@ public class DependencyCheckScanAgent {
|
||||
*
|
||||
* @param engine a dependency-check engine
|
||||
* @param outDirectory the directory to write the reports to
|
||||
* @throw ScanAgentException thrown if there is an error generating the
|
||||
* report
|
||||
*/
|
||||
private void generateExternalReports(Engine engine, File outDirectory) {
|
||||
DatabaseProperties prop = null;
|
||||
try (CveDB cve = CveDB.getInstance()) {
|
||||
prop = cve.getDatabaseProperties();
|
||||
} catch (DatabaseException ex) {
|
||||
//TODO shouldn't this be a fatal exception
|
||||
LOGGER.debug("Unable to retrieve DB Properties", ex);
|
||||
}
|
||||
final ReportGenerator r = new ReportGenerator(this.applicationName, engine.getDependencies(), engine.getAnalyzers(), prop);
|
||||
private void generateExternalReports(Engine engine, File outDirectory) throws ScanAgentException {
|
||||
try {
|
||||
r.generateReports(outDirectory.getCanonicalPath(), this.reportFormat.name());
|
||||
} catch (IOException | ReportException ex) {
|
||||
LOGGER.error("Unexpected exception occurred during analysis; please see the verbose error log for more details.");
|
||||
LOGGER.debug("", ex);
|
||||
engine.writeReports(applicationName, outDirectory, this.reportFormat.name());
|
||||
} catch (ReportException ex) {
|
||||
LOGGER.debug("Unexpected exception occurred during analysis; please see the verbose error log for more details.", ex);
|
||||
throw new ScanAgentException("Error generating the report", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -230,6 +230,16 @@ public final class CveDB implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method added for testing, returns the current usage count of the CveDB
|
||||
* singleton.
|
||||
*
|
||||
* @return the current usage of the CveDB singleton
|
||||
*/
|
||||
protected synchronized int getUsageCount() {
|
||||
return usageCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the database connection. If the database does not exist, it will
|
||||
* create a new one.
|
||||
|
||||
@@ -182,8 +182,8 @@ public class NvdCveUpdater implements CachedWebDataSource {
|
||||
LOGGER.trace("Ignorable exception", ex);
|
||||
}
|
||||
}
|
||||
if (lockFile != null) {
|
||||
lockFile.delete();
|
||||
if (lockFile != null && lockFile.isFile() && !lockFile.delete()) {
|
||||
LOGGER.error("Lock file '{}' was unable to be deleted. Please manually delete this file.", lockFile.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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) 2017 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.exception;
|
||||
|
||||
/**
|
||||
* An exception used when a dependency could not be found.
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
public class DependencyNotFoundException extends Exception {
|
||||
|
||||
/**
|
||||
* The serial version uid.
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates a new DependencyNotFoundException.
|
||||
*/
|
||||
public DependencyNotFoundException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new DependencyNotFoundException.
|
||||
*
|
||||
* @param msg a message for the exception.
|
||||
*/
|
||||
public DependencyNotFoundException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new DependencyNotFoundException.
|
||||
*
|
||||
* @param ex the cause of the exception.
|
||||
*/
|
||||
public DependencyNotFoundException(Throwable ex) {
|
||||
super(ex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new DependencyNotFoundException.
|
||||
*
|
||||
* @param msg a message for the exception.
|
||||
* @param ex the cause of the exception.
|
||||
*/
|
||||
public DependencyNotFoundException(String msg, Throwable ex) {
|
||||
super(msg, ex);
|
||||
}
|
||||
}
|
||||
@@ -19,13 +19,16 @@ package org.owasp.dependencycheck.reporting;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Set;
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.owasp.dependencycheck.dependency.Identifier;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* An extremely simple wrapper around various escape utils to perform URL and HTML encoding within the reports. This class was
|
||||
* created to simplify the velocity configuration and avoid using the "built-in" escape tool.
|
||||
* An extremely simple wrapper around various escape utils to perform URL and
|
||||
* HTML encoding within the reports. This class was created to simplify the
|
||||
* velocity configuration and avoid using the "built-in" escape tool.
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
@@ -80,4 +83,84 @@ public class EscapeTool {
|
||||
}
|
||||
return StringEscapeUtils.escapeXml11(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON Encodes the provided text.
|
||||
*
|
||||
* @param text the text to encode
|
||||
* @return the JSON encoded text
|
||||
*/
|
||||
public String json(String text) {
|
||||
if (text == null || text.isEmpty()) {
|
||||
return text;
|
||||
}
|
||||
return StringEscapeUtils.escapeJson(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats text for CSV format. This includes trimming whitespace, replace
|
||||
* line breaks with spaces, and if necessary quotes the text and/or escapes
|
||||
* contained quotes.
|
||||
*
|
||||
* @param text the text to escape and quote
|
||||
* @return the escaped and quoted text
|
||||
*/
|
||||
public String csv(String text) {
|
||||
if (text == null || text.isEmpty()) {
|
||||
return text;
|
||||
}
|
||||
return StringEscapeUtils.escapeCsv(text.trim().replace("\n", " "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a set of Identifiers, filters them to none CPE, and formats them
|
||||
* for display in a CSV.
|
||||
*
|
||||
* @param ids the set of identifiers
|
||||
* @return the formated list of none CPE identifiers
|
||||
*/
|
||||
public String csvIdentifiers(Set<Identifier> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
boolean addComma = false;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Identifier id : ids) {
|
||||
if (!"cpe".equals(id.getType())) {
|
||||
if (addComma) {
|
||||
sb.append(", ");
|
||||
} else {
|
||||
addComma = true;
|
||||
}
|
||||
sb.append(id.getValue());
|
||||
}
|
||||
}
|
||||
return StringEscapeUtils.escapeCsv(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a set of Identifiers, filters them to just CPEs, and formats them
|
||||
* for display in a CSV.
|
||||
*
|
||||
* @param ids the set of identifiers
|
||||
* @return the formated list of CPE identifiers
|
||||
*/
|
||||
public String csvCpe(Set<Identifier> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
boolean addComma = false;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Identifier id : ids) {
|
||||
if ("cpe".equals(id.getType())) {
|
||||
if (addComma) {
|
||||
sb.append(", ");
|
||||
} else {
|
||||
addComma = true;
|
||||
}
|
||||
sb.append(id.getValue());
|
||||
}
|
||||
}
|
||||
return StringEscapeUtils.escapeCsv(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,17 +17,16 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck.reporting;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import static com.google.gson.stream.JsonToken.*;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.context.Context;
|
||||
@@ -78,7 +77,15 @@ public class ReportGenerator {
|
||||
/**
|
||||
* Generate HTML Vulnerability report.
|
||||
*/
|
||||
VULN
|
||||
VULN,
|
||||
/**
|
||||
* Generate JSON report.
|
||||
*/
|
||||
JSON,
|
||||
/**
|
||||
* Generate CSV report.
|
||||
*/
|
||||
CSV
|
||||
}
|
||||
/**
|
||||
* The Velocity Engine.
|
||||
@@ -100,29 +107,35 @@ public class ReportGenerator {
|
||||
*/
|
||||
public ReportGenerator(String applicationName, List<Dependency> dependencies, List<Analyzer> analyzers, DatabaseProperties properties) {
|
||||
velocityEngine = createVelocityEngine();
|
||||
context = createContext();
|
||||
|
||||
velocityEngine.init();
|
||||
final EscapeTool enc = new EscapeTool();
|
||||
context = createContext(applicationName, dependencies, analyzers, properties);
|
||||
}
|
||||
|
||||
final DateTime dt = new DateTime();
|
||||
final DateTimeFormatter dateFormat = DateTimeFormat.forPattern("MMM d, yyyy 'at' HH:mm:ss z");
|
||||
final DateTimeFormatter dateFormatXML = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
|
||||
/**
|
||||
* Constructs a new ReportGenerator.
|
||||
*
|
||||
* @param applicationName the application name being analyzed
|
||||
* @param groupID the group id of the project being analyzed
|
||||
* @param artifactID the application id of the project being analyzed
|
||||
* @param version the application version of the project being analyzed
|
||||
* @param dependencies the list of dependencies
|
||||
* @param analyzers the list of analyzers used
|
||||
* @param properties the database properties (containing timestamps of the
|
||||
* NVD CVE data)
|
||||
*/
|
||||
public ReportGenerator(String applicationName, String groupID, String artifactID, String version,
|
||||
List<Dependency> dependencies, List<Analyzer> analyzers, DatabaseProperties properties) {
|
||||
|
||||
// final Date d = new Date();
|
||||
// final DateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy 'at' HH:mm:ss z");
|
||||
// final DateFormat dateFormatXML = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
|
||||
final String scanDate = dateFormat.print(dt);
|
||||
final String scanDateXML = dateFormatXML.print(dt);
|
||||
|
||||
context.put("applicationName", applicationName);
|
||||
context.put("dependencies", dependencies);
|
||||
context.put("analyzers", analyzers);
|
||||
context.put("properties", properties);
|
||||
context.put("scanDate", scanDate);
|
||||
context.put("scanDateXML", scanDateXML);
|
||||
context.put("enc", enc);
|
||||
context.put("version", Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown"));
|
||||
this(applicationName, dependencies, analyzers, properties);
|
||||
if (version != null) {
|
||||
context.put("applicationVersion", version);
|
||||
}
|
||||
if (artifactID != null) {
|
||||
context.put("artifactID", artifactID);
|
||||
}
|
||||
if (groupID != null) {
|
||||
context.put("groupID", groupID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,94 +151,162 @@ public class ReportGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Velocity Context.
|
||||
* Constructs the velocity context used to generate the dependency-check
|
||||
* reports.
|
||||
*
|
||||
* @return a Velocity Context
|
||||
* @param applicationName the application name being analyzed
|
||||
* @param dependencies the list of dependencies
|
||||
* @param analyzers the list of analyzers used
|
||||
* @param properties the database properties (containing timestamps of the
|
||||
* NVD CVE data)
|
||||
* @return the velocity context
|
||||
*/
|
||||
private Context createContext() {
|
||||
return new VelocityContext();
|
||||
private VelocityContext createContext(String applicationName, List<Dependency> dependencies, List<Analyzer> analyzers, DatabaseProperties properties) {
|
||||
final DateTime dt = new DateTime();
|
||||
final DateTimeFormatter dateFormat = DateTimeFormat.forPattern("MMM d, yyyy 'at' HH:mm:ss z");
|
||||
final DateTimeFormatter dateFormatXML = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
|
||||
|
||||
final String scanDate = dateFormat.print(dt);
|
||||
final String scanDateXML = dateFormatXML.print(dt);
|
||||
|
||||
VelocityContext ctxt = new VelocityContext();
|
||||
ctxt.put("applicationName", applicationName);
|
||||
ctxt.put("dependencies", dependencies);
|
||||
ctxt.put("analyzers", analyzers);
|
||||
ctxt.put("properties", properties);
|
||||
ctxt.put("scanDate", scanDate);
|
||||
ctxt.put("scanDateXML", scanDateXML);
|
||||
ctxt.put("enc", new EscapeTool());
|
||||
ctxt.put("version", Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown"));
|
||||
return ctxt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the Dependency Reports for the identified dependencies.
|
||||
* Writes the dependency-check report to the given output location.
|
||||
*
|
||||
* @param outputStream the OutputStream to send the generated report to
|
||||
* @param format the format the report should be written in
|
||||
* @throws IOException is thrown when the template file does not exist
|
||||
* @throws Exception is thrown if there is an error writing out the reports
|
||||
*/
|
||||
public void generateReports(OutputStream outputStream, Format format) throws IOException, Exception {
|
||||
if (format == Format.XML || format == Format.ALL) {
|
||||
generateReport("XmlReport", outputStream);
|
||||
}
|
||||
if (format == Format.HTML || format == Format.ALL) {
|
||||
generateReport("HtmlReport", outputStream);
|
||||
}
|
||||
if (format == Format.VULN || format == Format.ALL) {
|
||||
generateReport("VulnerabilityReport", outputStream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the Dependency Reports for the identified dependencies.
|
||||
*
|
||||
* @param outputDir the path where the reports should be written
|
||||
* @param format the format the report should be written in
|
||||
* @throws ReportException is thrown if there is an error writing out the
|
||||
* reports
|
||||
*/
|
||||
public void generateReports(String outputDir, Format format) throws ReportException {
|
||||
if (format == Format.XML || format == Format.ALL) {
|
||||
generateReport("XmlReport", outputDir + File.separator + "dependency-check-report.xml");
|
||||
}
|
||||
if (format == Format.HTML || format == Format.ALL) {
|
||||
generateReport("HtmlReport", outputDir + File.separator + "dependency-check-report.html");
|
||||
}
|
||||
if (format == Format.VULN || format == Format.ALL) {
|
||||
generateReport("VulnerabilityReport", outputDir + File.separator + "dependency-check-vulnerability.html");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the Dependency Reports for the identified dependencies.
|
||||
*
|
||||
* @param outputDir the path where the reports should be written
|
||||
* @param outputFormat the format the report should be written in (XML,
|
||||
* HTML, ALL)
|
||||
* @param outputLocation the path where the reports should be written
|
||||
* @param format the format the report should be written in (XML, HTML,
|
||||
* JSON, CSV, ALL) or even the path to a custom velocity template (either
|
||||
* fully qualified or the template name on the class path).
|
||||
* @throws ReportException is thrown if there is an error creating out the
|
||||
* reports
|
||||
*/
|
||||
public void generateReports(String outputDir, String outputFormat) throws ReportException {
|
||||
final String format = outputFormat.toUpperCase();
|
||||
final String pathToCheck = outputDir.toLowerCase();
|
||||
if (format.matches("^(XML|HTML|VULN|ALL)$")) {
|
||||
if ("XML".equalsIgnoreCase(format)) {
|
||||
if (pathToCheck.endsWith(".xml")) {
|
||||
generateReport("XmlReport", outputDir);
|
||||
} else {
|
||||
generateReports(outputDir, Format.XML);
|
||||
public void write(String outputLocation, String format) throws ReportException {
|
||||
Format reportFormat = null;
|
||||
try {
|
||||
reportFormat = Format.valueOf(format.toUpperCase());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
LOGGER.trace("ignore this exception", ex);
|
||||
}
|
||||
|
||||
if (reportFormat != null) {
|
||||
write(outputLocation, reportFormat);
|
||||
} else {
|
||||
File out = getReportFile(outputLocation, null);
|
||||
if (out.isDirectory()) {
|
||||
throw new ReportException("Unable to write non-standard VSL output to a directory, please specify a file name");
|
||||
}
|
||||
processTemplate(format, out);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the dependency-check report(s).
|
||||
*
|
||||
* @param outputLocation the path where the reports should be written
|
||||
* @param format the format the report should be written in (XML, HTML, ALL)
|
||||
* @throws ReportException is thrown if there is an error creating out the
|
||||
* reports
|
||||
*/
|
||||
public void write(String outputLocation, Format format) throws ReportException {
|
||||
if (format == Format.ALL) {
|
||||
for (Format f : Format.values()) {
|
||||
if (f != Format.ALL) {
|
||||
write(outputLocation, f);
|
||||
}
|
||||
}
|
||||
if ("HTML".equalsIgnoreCase(format)) {
|
||||
if (pathToCheck.endsWith(".html") || pathToCheck.endsWith(".htm")) {
|
||||
generateReport("HtmlReport", outputDir);
|
||||
} else {
|
||||
generateReports(outputDir, Format.HTML);
|
||||
}
|
||||
}
|
||||
if ("VULN".equalsIgnoreCase(format)) {
|
||||
if (pathToCheck.endsWith(".html") || pathToCheck.endsWith(".htm")) {
|
||||
generateReport("VulnReport", outputDir);
|
||||
} else {
|
||||
generateReports(outputDir, Format.VULN);
|
||||
}
|
||||
}
|
||||
if ("ALL".equalsIgnoreCase(format)) {
|
||||
generateReports(outputDir, Format.ALL);
|
||||
} else {
|
||||
final File out = getReportFile(outputLocation, format);
|
||||
final String templateName = format.toString().toLowerCase() + "Report";
|
||||
processTemplate(templateName, out);
|
||||
if (format == Format.JSON) {
|
||||
pretifyJson(out.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Writes the dependency-check report(s).
|
||||
// *
|
||||
// * @param outputStream the OutputStream to send the generated report to
|
||||
// * @param format the format the report should be written in
|
||||
// * @throws ReportException thrown if the report format is ALL
|
||||
// * @throws IOException is thrown when the template file does not exist
|
||||
// * @throws Exception is thrown if there is an error writing out the reports
|
||||
// */
|
||||
// public void write(OutputStream outputStream, Format format) throws ReportException, IOException, Exception {
|
||||
// if (format == Format.ALL) {
|
||||
// throw new ReportException("Unable to write ALL reports to a single output stream, please check the API");
|
||||
// }
|
||||
// final String templateName = format.toString().toLowerCase() + "Report";
|
||||
// processTemplate(templateName, outputStream);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Determines the report file name based on the give output location and
|
||||
* format. If the output location contains a full file name that has the
|
||||
* correct extension for the given report type then the output location is
|
||||
* returned. However, if the output location is a directory, this method
|
||||
* will generate the correct name for the given output format.
|
||||
*
|
||||
* @param outputLocation the specified output location
|
||||
* @param format the report format
|
||||
* @return the report File
|
||||
*/
|
||||
protected File getReportFile(String outputLocation, Format format) {
|
||||
File outFile = new File(outputLocation);
|
||||
if (outFile.getParentFile() == null) {
|
||||
outFile = new File(".", outputLocation);
|
||||
}
|
||||
final String pathToCheck = outputLocation.toLowerCase();
|
||||
if (format == Format.XML && !pathToCheck.endsWith(".xml")) {
|
||||
return new File(outFile, "dependency-check-report.xml");
|
||||
}
|
||||
if (format == Format.HTML && !pathToCheck.endsWith(".html") && !pathToCheck.endsWith(".htm")) {
|
||||
return new File(outFile, "dependency-check-report.html");
|
||||
}
|
||||
if (format == Format.VULN && !pathToCheck.endsWith(".html") && !pathToCheck.endsWith(".htm")) {
|
||||
return new File(outFile, "dependency-check-vulnerability.html");
|
||||
}
|
||||
if (format == Format.JSON && !pathToCheck.endsWith(".json")) {
|
||||
return new File(outFile, "dependency-check-report.json");
|
||||
}
|
||||
if (format == Format.CSV && !pathToCheck.endsWith(".csv")) {
|
||||
return new File(outFile, "dependency-check-report.csv");
|
||||
}
|
||||
return outFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a report from a given Velocity Template. The template name
|
||||
* provided can be the name of a template contained in the jar file, such as
|
||||
* 'XmlReport' or 'HtmlReport', or the template name can be the path to a
|
||||
* template file.
|
||||
*
|
||||
* @param template the name of the template to load
|
||||
* @param file the output file to write the report to
|
||||
* @throws ReportException is thrown when the report cannot be generated
|
||||
*/
|
||||
protected void processTemplate(String template, File file) throws ReportException {
|
||||
ensureParentDirectoryExists(file);
|
||||
try (OutputStream output = new FileOutputStream(file)) {
|
||||
processTemplate(template, output);
|
||||
} catch (IOException ex) {
|
||||
throw new ReportException(String.format("Unable to write to file: %s", file), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a report from a given Velocity Template. The template name
|
||||
* provided can be the name of a template contained in the jar file, such as
|
||||
@@ -236,29 +317,33 @@ public class ReportGenerator {
|
||||
* @param outputStream the OutputStream to write the report to
|
||||
* @throws ReportException is thrown when an exception occurs
|
||||
*/
|
||||
protected void generateReport(String templateName, OutputStream outputStream) throws ReportException {
|
||||
protected void processTemplate(String templateName, OutputStream outputStream) throws ReportException {
|
||||
InputStream input = null;
|
||||
String templatePath = null;
|
||||
String logTag = null;
|
||||
final File f = new File(templateName);
|
||||
try {
|
||||
if (f.exists() && f.isFile()) {
|
||||
if (f.isFile()) {
|
||||
try {
|
||||
templatePath = templateName;
|
||||
logTag = templateName;
|
||||
input = new FileInputStream(f);
|
||||
} catch (FileNotFoundException ex) {
|
||||
throw new ReportException("Unable to locate template file: " + templateName, ex);
|
||||
}
|
||||
} else {
|
||||
templatePath = "templates/" + templateName + ".vsl";
|
||||
input = this.getClass().getClassLoader().getResourceAsStream(templatePath);
|
||||
logTag = "templates/" + templateName + ".vsl";
|
||||
input = this.getClass().getClassLoader().getResourceAsStream(logTag);
|
||||
}
|
||||
if (input == null) {
|
||||
throw new ReportException("Template file doesn't exist: " + templatePath);
|
||||
logTag = templateName;
|
||||
input = this.getClass().getClassLoader().getResourceAsStream(templateName);
|
||||
}
|
||||
if (input == null) {
|
||||
throw new ReportException("Template file doesn't exist: " + logTag);
|
||||
}
|
||||
|
||||
try (InputStreamReader reader = new InputStreamReader(input, "UTF-8");
|
||||
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8")) {
|
||||
if (!velocityEngine.evaluate(context, writer, templatePath, reader)) {
|
||||
if (!velocityEngine.evaluate(context, writer, logTag, reader)) {
|
||||
throw new ReportException("Failed to convert the template into html.");
|
||||
}
|
||||
writer.flush();
|
||||
@@ -277,32 +362,106 @@ public class ReportGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a report from a given Velocity Template. The template name
|
||||
* provided can be the name of a template contained in the jar file, such as
|
||||
* 'XmlReport' or 'HtmlReport', or the template name can be the path to a
|
||||
* template file.
|
||||
* Validates that the given file's parent directory exists. If the directory
|
||||
* does not exist an attempt to create the necessary path is made; if that
|
||||
* fails a ReportException will be raised.
|
||||
*
|
||||
* @param templateName the name of the template to load
|
||||
* @param outFileName the filename and path to write the report to
|
||||
* @throws ReportException is thrown when the report cannot be generated
|
||||
* @param file the file or directory directory
|
||||
* @throws ReportException thrown if the parent directory does not exist and
|
||||
* cannot be created
|
||||
*/
|
||||
protected void generateReport(String templateName, String outFileName) throws ReportException {
|
||||
File outFile = new File(outFileName);
|
||||
if (outFile.getParentFile() == null) {
|
||||
outFile = new File(".", outFileName);
|
||||
}
|
||||
if (!outFile.getParentFile().exists()) {
|
||||
final boolean created = outFile.getParentFile().mkdirs();
|
||||
private void ensureParentDirectoryExists(File file) throws ReportException {
|
||||
if (!file.getParentFile().exists()) {
|
||||
final boolean created = file.getParentFile().mkdirs();
|
||||
if (!created) {
|
||||
throw new ReportException("Unable to create directory '" + outFile.getParentFile().getAbsolutePath() + "'.");
|
||||
final String msg = String.format("Unable to create directory '%s'.", file.getParentFile().getAbsolutePath());
|
||||
throw new ReportException(msg);
|
||||
}
|
||||
}
|
||||
try (OutputStream outputSteam = new FileOutputStream(outFile)) {
|
||||
generateReport(templateName, outputSteam);
|
||||
}
|
||||
/**
|
||||
* Reformats the given JSON file.
|
||||
*
|
||||
* @param pathToJson the path to the JSON file to be reformatted
|
||||
* @throws JsonSyntaxException thrown if the given JSON file is malformed
|
||||
*/
|
||||
private void pretifyJson(String pathToJson) throws JsonSyntaxException {
|
||||
final String outputPath = pathToJson + ".pretty";
|
||||
final File in = new File(pathToJson);
|
||||
final File out = new File(outputPath);
|
||||
try (JsonReader reader = new JsonReader(new InputStreamReader(new FileInputStream(in), StandardCharsets.UTF_8));
|
||||
JsonWriter writer = new JsonWriter(new OutputStreamWriter(new FileOutputStream(out), StandardCharsets.UTF_8))) {
|
||||
prettyPrint(reader, writer);
|
||||
} catch (IOException ex) {
|
||||
throw new ReportException("Unable to write to file: " + outFile, ex);
|
||||
LOGGER.error("Unable to generate pretty report, caused by: ", ex.getMessage());
|
||||
return;
|
||||
}
|
||||
if (out.isFile() && in.isFile() && in.delete()) {
|
||||
try {
|
||||
org.apache.commons.io.FileUtils.moveFile(out, in);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.error("Unable to generate pretty report, caused by: ", ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Streams from a json reader to a json writer and performs pretty printing.
|
||||
*
|
||||
* This function is copied from https://sites.google.com/site/gson/streaming
|
||||
*
|
||||
* @param reader json reader
|
||||
* @param writer json writer
|
||||
* @throws IOException thrown if the json is malformed
|
||||
*/
|
||||
private static void prettyPrint(JsonReader reader, JsonWriter writer) throws IOException {
|
||||
writer.setIndent(" ");
|
||||
while (true) {
|
||||
final JsonToken token = reader.peek();
|
||||
switch (token) {
|
||||
case BEGIN_ARRAY:
|
||||
reader.beginArray();
|
||||
writer.beginArray();
|
||||
break;
|
||||
case END_ARRAY:
|
||||
reader.endArray();
|
||||
writer.endArray();
|
||||
break;
|
||||
case BEGIN_OBJECT:
|
||||
reader.beginObject();
|
||||
writer.beginObject();
|
||||
break;
|
||||
case END_OBJECT:
|
||||
reader.endObject();
|
||||
writer.endObject();
|
||||
break;
|
||||
case NAME:
|
||||
final String name = reader.nextName();
|
||||
writer.name(name);
|
||||
break;
|
||||
case STRING:
|
||||
final String s = reader.nextString();
|
||||
writer.value(s);
|
||||
break;
|
||||
case NUMBER:
|
||||
final String n = reader.nextString();
|
||||
writer.value(new BigDecimal(n));
|
||||
break;
|
||||
case BOOLEAN:
|
||||
final boolean b = reader.nextBoolean();
|
||||
writer.value(b);
|
||||
break;
|
||||
case NULL:
|
||||
reader.nextNull();
|
||||
writer.nullValue();
|
||||
break;
|
||||
case END_DOCUMENT:
|
||||
return;
|
||||
default:
|
||||
LOGGER.debug("Unexpected JSON toekn {}", token.toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public class PomParser {
|
||||
return parse(fis);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.debug("", ex);
|
||||
throw new PomParseException(ex);
|
||||
throw new PomParseException(String.format("Unable to parse pom '%s'", file.toString()), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.1.xsd">
|
||||
<suppress base="true">
|
||||
<notes><![CDATA[
|
||||
This suppresses false positives for Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll.
|
||||
]]></notes>
|
||||
<filePath regex="true">.*Microsoft\.VisualStudio\.QualityTools\.UnitTestFramework*\.dll</filePath>
|
||||
<cve>CVE-2014-3802</cve>
|
||||
</suppress>
|
||||
<suppress base="true">
|
||||
<notes><![CDATA[
|
||||
This suppresses false positives for EntityFramework.SqlServer.dll.
|
||||
]]></notes>
|
||||
<filePath regex="true">.*EntityFramework\.SqlServer*\.dll</filePath>
|
||||
<cpe>cpe:/a:microsoft:server:6.0.0.0</cpe>
|
||||
<cpe>cpe:/a:microsoft:sql_server:6.0</cpe>
|
||||
</suppress>
|
||||
<suppress base="true">
|
||||
<notes><![CDATA[
|
||||
This suppresses false positives identified on spring security.
|
||||
@@ -561,4 +576,36 @@
|
||||
<gav regex="true">^org\.springframework\.boot:spring-boot-starter-data-jpa:.*$</gav>
|
||||
<cve>CVE-2016-6652</cve>
|
||||
</suppress>
|
||||
<suppress base="true">
|
||||
<notes><![CDATA[
|
||||
False positive per issue #699
|
||||
]]></notes>
|
||||
<gav regex="true">^com\.splunk:splunk:.*$</gav>
|
||||
<cpe>cpe:/a:splunk:splunk</cpe>
|
||||
</suppress>
|
||||
<suppress base="true">
|
||||
<notes><![CDATA[
|
||||
False positive per issue #713
|
||||
]]></notes>
|
||||
<gav regex="true">^org\.openid4java:openid4java:.*$</gav>
|
||||
<cpe>cpe:/a:openid:openid</cpe>
|
||||
<cpe>cpe:/a:openid:openid4java</cpe>
|
||||
</suppress>
|
||||
<suppress base="true">
|
||||
<notes><![CDATA[
|
||||
False positive per issue #700
|
||||
]]></notes>
|
||||
<gav regex="true">^org\.springframework\.cloud:spring-cloud-netflix-core:.*$</gav>
|
||||
<cpe>cpe:/a:pivotal:spring_framework</cpe>
|
||||
<cpe>cpe:/a:pivotal_software:spring_framework</cpe>
|
||||
</suppress>
|
||||
<suppress base="true">
|
||||
<notes><![CDATA[
|
||||
False positive per issue #700
|
||||
]]></notes>
|
||||
<gav regex="true">^org\.springframework\.cloud:spring-cloud-.*$</gav>
|
||||
<cpe>cpe:/a:pivotal:spring_framework</cpe>
|
||||
<cpe>cpe:/a:pivotal_software:spring_framework</cpe>
|
||||
<cpe>cpe:/a:context_project:context</cpe>
|
||||
</suppress>
|
||||
</suppressions>
|
||||
|
||||
@@ -41,6 +41,8 @@ data.password=DC-Pass1337!
|
||||
data.driver_name=org.h2.Driver
|
||||
data.driver_path=
|
||||
|
||||
|
||||
proxy.disableSchemas=true
|
||||
# the number of days that the modified nvd cve data holds data for. We don't need
|
||||
# to update the other files if we are within this timespan. Per NIST this file
|
||||
# holds 8 days of updates, we are using 7 just to be safe.
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema id="analysis"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
elementFormDefault="qualified"
|
||||
targetNamespace="https://jeremylong.github.io/DependencyCheck/dependency-check.1.5.xsd"
|
||||
xmlns:dc="https://jeremylong.github.io/DependencyCheck/dependency-check.1.5.xsd">
|
||||
|
||||
<xs:complexType name="scanInfo">
|
||||
<xs:sequence minOccurs="1" maxOccurs="1">
|
||||
<xs:element name="engineVersion" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="dataSource">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="timestamp" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="projectInfo">
|
||||
<xs:sequence>
|
||||
<xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="groupID" type="xs:string" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="artifactID" type="xs:string" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="version" type="xs:string" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="reportDate" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="credits" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="identifier">
|
||||
<xs:sequence>
|
||||
<xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="url" type="xs:string" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="notes" type="xs:string" minOccurs="0" maxOccurs="1" />
|
||||
</xs:sequence>
|
||||
<xs:attribute name="type" type="xs:string" use="required" />
|
||||
<xs:attribute name="confidence" type="xs:string" use="optional" />
|
||||
</xs:complexType>
|
||||
<xs:complexType name="relatedDependency">
|
||||
<xs:sequence>
|
||||
<xs:element name="filePath" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="sha1" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="md5" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="identifier" type="dc:identifier" />
|
||||
</xs:sequence>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="exception">
|
||||
<xs:sequence>
|
||||
<xs:element name="message" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xs:element name="stackTrace" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="trace" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="innerException" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="message" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xs:element name="stackTrace" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="trace" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="evidence">
|
||||
<xs:sequence>
|
||||
<xs:element name="source" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="value" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
</xs:sequence>
|
||||
<xs:attribute name="type" type="xs:string" use="required" />
|
||||
<xs:attribute name="confidence" type="xs:string" use="required" />
|
||||
</xs:complexType>
|
||||
<xs:complexType name="reference">
|
||||
<xs:sequence>
|
||||
<xs:element name="source" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="url" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="software">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute name="allPreviousVersion" type="xs:boolean" />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="vulnerability">
|
||||
<xs:sequence>
|
||||
<xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="cvssScore" type="xs:decimal" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="cvssAccessVector" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="cvssAccessComplexity" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="cvssAuthenticationr" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="cvssConfidentialImpact" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="cvssIntegrityImpact" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="cvssAvailabilityImpact" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="severity" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="cwe" type="xs:string" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="description" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="notes" type="xs:string" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="references" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="reference" type="dc:reference" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="vulnerableSoftware" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="software" type="dc:software" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="dependency">
|
||||
<xs:sequence>
|
||||
<xs:element name="fileName" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="filePath" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="md5" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="sha1" type="xs:string" minOccurs="1" maxOccurs="1" />
|
||||
<xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="license" type="xs:string" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="relatedDependencies" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="relatedDependency" type="dc:relatedDependency" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="analysisExceptions" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="exception" type="dc:exception"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="evidenceCollected" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="evidence" type="dc:evidence"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="identifiers" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="identifier" type="dc:identifier" />
|
||||
</xs:sequence>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="suppressedIdentifier" type="dc:identifier"/>
|
||||
</xs:sequence>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="vulnerabilities" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="vulnerability" type="dc:vulnerability"/>
|
||||
</xs:sequence>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="suppressedVulnerability" type="dc:vulnerability"/>
|
||||
</xs:sequence>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name="analysis">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="scanInfo" type="dc:scanInfo"/>
|
||||
<xs:element name="projectInfo" type="dc:projectInfo"/>
|
||||
<xs:element name="dependencies">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="dependency" type="dc:dependency"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,27 @@
|
||||
#**
|
||||
This file is part of Dependency-Check.
|
||||
|
||||
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) 2017 Jeremy Long. All Rights Reserved.
|
||||
|
||||
@author Jeremy Long <jeremy.long@owasp.org>
|
||||
@version 1 *###
|
||||
"Project","ScanDate","DependencyName","DependencyPath","Description","License","Md5","Sha1","Identifiers","CPE","CVE","CWE","Vulnerability","Severity","CVSSv2"
|
||||
#macro(writeSev $score)#if($score<4.0)"Low"#elseif($score>=7.0)"High"#else"Medium"#end#end
|
||||
#foreach($dependency in $dependencies)#if($dependency.getVulnerabilities().size()>0)
|
||||
#foreach($vuln in $dependency.getVulnerabilities())
|
||||
$enc.csv($applicationName),$enc.csv($scanDate),$enc.csv($dependency.DisplayFileName),#if($dependency.FilePath)$enc.csv($dependency.FilePath)#end,#if($dependency.description)$enc.csv($dependency.description)#end,#if($dependency.license)$enc.csv($dependency.license)#end,#if($dependency.Md5sum)$enc.csv($dependency.Md5sum)#end,#if($dependency.Sha1sum)$enc.csv($dependency.Sha1sum)#end,#if($dependency.identifiers)$enc.csvIdentifiers($dependency.identifiers)#end,#if($dependency.identifiers)$enc.csvCpe($dependency.identifiers)#end,#if($vuln.name)$enc.csv($vuln.name)#end,#if($dependency.cwe)$enc.csv($vuln.cwe)#end,#if($vuln.description)$enc.csv($vuln.description)#end,#writeSev($vuln.cvssScore),$vuln.cvssScore
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
@@ -632,7 +632,7 @@ Getting Help: <a href="https://groups.google.com/forum/#!forum/dependency-check"
|
||||
#foreach($dependency in $dependencies)
|
||||
#set($lnkcnt=$lnkcnt+1)
|
||||
<tr class="#if($dependency.getVulnerabilities().size()==0)notvulnerable#else vulnerable#end">
|
||||
<td data-sort-value="$enc.html($dependency.DisplayFileName)"><a href="#l${lnkcnt}_$enc.html($enc.url($dependency.Sha1sum))">$enc.html($dependency.DisplayFileName)</a></td>
|
||||
<td data-sort-value="$enc.html($dependency.DisplayFileName.toUpperCase())"><a href="#l${lnkcnt}_$enc.html($enc.url($dependency.Sha1sum))">$enc.html($dependency.DisplayFileName)</a></td>
|
||||
#set($mavenlink="")
|
||||
#set($cpeIdCount=0)
|
||||
#set($cpeIdConf="")
|
||||
@@ -673,9 +673,9 @@ Getting Help: <a href="https://groups.google.com/forum/#!forum/dependency-check"
|
||||
#if ($mavenlink=="")
|
||||
<td data-sort-value="">
|
||||
#else
|
||||
<td data-sort-value="$enc.html($mavenlink.value)">#if( $mavenlink.url )
|
||||
<td data-sort-value="$enc.html($mavenlink.value.toLowerCase())">#if( $mavenlink.url )
|
||||
##yes, we are HTML Encoding the href. This is okay. We can't URL encode as we have to trust the analyzer here...
|
||||
<a href="$enc.html($mavenlink.url)" target="_blank">$enc.html($mavenlink.value)</a>
|
||||
<a href="$enc.html($mavenlink.url)" target="_blank">$enc.html($mavenlink.value)</a> <span title="verified from repo" style="color:green">✓</span>
|
||||
#elseif ($mavenlink.value)
|
||||
$enc.html($mavenlink.value)
|
||||
#end
|
||||
@@ -762,10 +762,10 @@ Getting Help: <a href="https://groups.google.com/forum/#!forum/dependency-check"
|
||||
<li>SHA1: $enc.html($related.Sha1sum)</li>
|
||||
<li>MD5: $enc.html($related.Md5sum)</li>
|
||||
#foreach($id in $related.getIdentifiers())
|
||||
#if ($id.type=="maven")
|
||||
#if( $id.url )
|
||||
#if( $id.url )
|
||||
#if ($id.type=="maven")
|
||||
##yes, we are HTML Encoding the href. this is okay. We can't URL encode as we have to trust the analyzer here...
|
||||
<li>$enc.html($id.type): <a href="$enc.html($id.url)" target="_blank">$enc.html($id.value)</a>
|
||||
<li>$enc.html($id.type): <a href="$enc.html($id.url)" target="_blank">$enc.html($id.value)</a> <span title="verified from repo" style="color:green">✓</span>
|
||||
#else
|
||||
<li>$enc.html($id.type): $enc.html($id.value)
|
||||
#end
|
||||
@@ -800,8 +800,12 @@ Getting Help: <a href="https://groups.google.com/forum/#!forum/dependency-check"
|
||||
#end
|
||||
#foreach($id in $dependency.getIdentifiers())
|
||||
#if( $id.url )
|
||||
#if($id.type=="maven")
|
||||
##yes, we are HTML Encoding the href. this is okay. We can't URL encode as we have to trust the analyzer here...
|
||||
<li><b>$enc.html($id.type):</b> <a href="$enc.html($id.url)" target="_blank">$enc.html($id.value)</a> <span title="verified from repo" style="color:green">✓</span>
|
||||
#else
|
||||
<li><b>$enc.html($id.type):</b> <a href="$enc.html($id.url)" target="_blank">$enc.html($id.value)</a>
|
||||
#end
|
||||
#else
|
||||
<li><b>$enc.html($id.type):</b> $enc.html($id.value)
|
||||
#end
|
||||
@@ -949,8 +953,12 @@ Getting Help: <a href="https://groups.google.com/forum/#!forum/dependency-check"
|
||||
<ul>
|
||||
#foreach($id in $dependency.getSuppressedIdentifiers())
|
||||
#if( $id.url )
|
||||
#if($id.type=="maven")
|
||||
##yes, we are HTML Encoding the href. this is okay. We can't URL encode as we have to trust the analyzer here...
|
||||
<li><b>$enc.html($id.type):</b> <a href="$enc.html($id.url)" target="_blank">$enc.html($id.value)</a> <span title="verified from repo" style="color:green">✓</span> <span class="suppressedLabel" >suppressed</span>
|
||||
#else
|
||||
<li><b>$enc.html($id.type):</b> <a href="$enc.html($id.url)" target="_blank">$enc.html($id.value)</a> <span class="suppressedLabel" >suppressed</span>
|
||||
#end
|
||||
#else
|
||||
<li><b>$enc.html($id.type):</b> $enc.html($id.value) <span class="suppressedLabel" >suppressed</span>
|
||||
#end
|
||||
@@ -0,0 +1,182 @@
|
||||
{
|
||||
"reportSchema": "1.0",
|
||||
"scanInfo": {
|
||||
"engineVersion": "$version",
|
||||
"dataSource": [
|
||||
#foreach($prop in $properties.getMetaData().entrySet())
|
||||
#if($foreach.count > 1),#end{
|
||||
"name": "$enc.json($prop.key)",
|
||||
"timestamp": "$enc.json($prop.value)"
|
||||
}
|
||||
#end
|
||||
]
|
||||
},
|
||||
"projectInfo": {
|
||||
"name": "$enc.json($applicationName)",
|
||||
#if($groupID)"groupID":"$enc.json($groupID)",#end
|
||||
#if($artifactID)"artifactID":"$enc.json($artifactID)",#end
|
||||
#if($version)"version":"$enc.json($version)",#end
|
||||
"reportDate": "$scanDateXML",
|
||||
"credits": "This report contains data retrieved from the National Vulnerability Database: http://nvd.nist.gov"
|
||||
},
|
||||
"dependencies": [
|
||||
#foreach($dependency in $dependencies)#if($foreach.count > 1),#end{
|
||||
"fileName": "$enc.json($dependency.DisplayFileName)",
|
||||
"filePath": "$enc.json($dependency.FilePath)",
|
||||
"md5": "$enc.json($dependency.Md5sum)",
|
||||
"sha1": "$enc.json($dependency.Sha1sum)"
|
||||
#if($dependency.description),"description": "$enc.json($dependency.description)"#end
|
||||
#if($dependency.license),"license": "$enc.json($dependency.license)"#end
|
||||
#if ($dependency.getRelatedDependencies().size()>0)
|
||||
,"relatedDependencies": [
|
||||
#foreach($related in $dependency.getRelatedDependencies()) #if($foreach.count > 1),#end {
|
||||
"filePath": "$enc.json($related.FilePath)",
|
||||
"sha1": "$enc.json($related.Sha1sum)",
|
||||
"md5": "$enc.json($related.Md5sum)"#if($related.getIdentifiers()),#end
|
||||
"identifiers": [
|
||||
#foreach($id in $related.getIdentifiers())
|
||||
#if ($id.type=="maven")
|
||||
{
|
||||
"type": "$enc.json($id.type)",
|
||||
"name": "$id.value"
|
||||
#if( $id.url ),"url": "$enc.json($id.url)"#end
|
||||
#if ($id.notes),"notes": "$enc.json($id.notes)"#end
|
||||
}
|
||||
#end
|
||||
#end
|
||||
]
|
||||
}
|
||||
#end
|
||||
]
|
||||
#end
|
||||
,"evidenceCollected": {
|
||||
"vendorEvidence": [
|
||||
#foreach($evidence in $dependency.getVendorEvidence())
|
||||
#if($foreach.count > 1),#end{
|
||||
"type": "vendor",
|
||||
"confidence": "$enc.json($evidence.getConfidence().toString())",
|
||||
"source": "$enc.json($evidence.getSource())",
|
||||
"name": "$enc.json($evidence.getName())",
|
||||
"value": "$enc.json($evidence.getValue().trim())"
|
||||
}
|
||||
#end
|
||||
],
|
||||
"productEvidence": [
|
||||
#foreach($evidence in $dependency.getProductEvidence())
|
||||
#if($foreach.count > 1),#end{
|
||||
"type": "product",
|
||||
"confidence": "$enc.json($evidence.getConfidence().toString())",
|
||||
"source": "$enc.json($evidence.getSource())",
|
||||
"name": "$enc.json($evidence.getName())",
|
||||
"value": "$enc.json($evidence.getValue().trim())"
|
||||
}
|
||||
#end
|
||||
],
|
||||
"versionEvidence": [
|
||||
#foreach($evidence in $dependency.getVersionEvidence())
|
||||
#if($foreach.count > 1),#end{
|
||||
"type": "version",
|
||||
"confidence": "$enc.json($evidence.getConfidence().toString())",
|
||||
"source": "$enc.json($evidence.getSource())",
|
||||
"name": "$enc.json($evidence.getName())",
|
||||
"value": "$enc.json($evidence.getValue().trim())"
|
||||
}
|
||||
#end
|
||||
]
|
||||
},
|
||||
"identifiers": [
|
||||
#foreach($id in $dependency.getIdentifiers())#if($foreach.count > 1),#end{
|
||||
"name": "$id.value",
|
||||
"type": "$enc.json($id.type)",
|
||||
#if($id.confidence)"confidence": "$id.confidence",#end
|
||||
#if($id.url)"url": "$enc.json($id.url)",#end
|
||||
#if($id.description )"description": "$enc.json($id.description)",#end
|
||||
#if ($id.notes)"notes": "$enc.json($id.notes)",#end
|
||||
"suppressedIdentifiers": [
|
||||
#foreach($id in $dependency.getSuppressedIdentifiers())
|
||||
#if($foreach.count > 1),#end{
|
||||
"type": "$enc.json($id.type)",
|
||||
#if($id.confidence)"confidence": "$id.confidence",#end
|
||||
"name": "$id.value",
|
||||
#if($id.url)"url": "$enc.json($id.url),"#end
|
||||
#if($id.description)"description": "$enc.json($id.description)",#end
|
||||
#if ($id.notes)"notes": "$enc.json($id.notes)"#end
|
||||
}
|
||||
#end
|
||||
]
|
||||
}
|
||||
#end
|
||||
]
|
||||
#if($dependency.getVulnerabilities().size()>0 || $dependency.getSuppressedVulnerabilities().size()>0)
|
||||
,"vulnerabilities": [
|
||||
#foreach($vuln in $dependency.getVulnerabilities())#if($foreach.count > 1),#end {
|
||||
"name": "$enc.json($vuln.name)",
|
||||
"cvssScore": "$vuln.cvssScore",
|
||||
"cvssAccessVector": "$enc.json($vuln.cvssAccessVector)",
|
||||
"cvssAccessComplexity": "$enc.json($vuln.cvssAccessComplexity)",
|
||||
"cvssAuthenticationr": "$enc.json($vuln.cvssAuthentication)",
|
||||
"cvssConfidentialImpact": "$enc.json($vuln.cvssConfidentialityImpact)",
|
||||
"cvssIntegrityImpact": "$enc.json($vuln.cvssIntegrityImpact)",
|
||||
"cvssAvailabilityImpact": "$enc.json($vuln.cvssAvailabilityImpact)",
|
||||
#if ($vuln.cvssScore<4.0)"severity": "Low",
|
||||
#elseif ($vuln.cvssScore>=7.0)"severity": "High",
|
||||
#else "severity": "Medium",#end
|
||||
"cwe": "#if ($vuln.cwe)$enc.json($vuln.cwe)#end",
|
||||
"description": "$enc.json($vuln.description)",
|
||||
"notes": "#if ($vuln.notes)$enc.json($vuln.notes)#end",
|
||||
"references": [
|
||||
#foreach($ref in $vuln.getReferences())
|
||||
#if($foreach.count > 1),#end {
|
||||
"source": "$enc.json($ref.source)",
|
||||
"url": "$enc.json($ref.url)",
|
||||
"name": "$enc.json($ref.name)"
|
||||
}#end
|
||||
],
|
||||
"vulnerableSoftware": [
|
||||
#foreach($vs in $vuln.getVulnerableSoftware())
|
||||
#if($foreach.count > 1),#end {
|
||||
"software": "$enc.json($vs.name)"
|
||||
#if($vs.hasPreviousVersion()) ,"allPreviousVersion": "true"#end
|
||||
}#end
|
||||
]
|
||||
}#end
|
||||
]#end
|
||||
|
||||
#if($dependency.getSuppressedVulnerabilities().size()>0 || $dependency.getSuppressedVulnerabilities().size()>0)
|
||||
,"suppressedVulnerabilities": [
|
||||
#foreach($vuln in $dependency.getSuppressedVulnerabilities())#if($foreach.count > 1),#end {
|
||||
"name": "$enc.json($vuln.name)",
|
||||
"cvssScore": "$vuln.cvssScore",
|
||||
"cvssAccessVector": "$enc.json($vuln.cvssAccessVector)",
|
||||
"cvssAccessComplexity": "$enc.json($vuln.cvssAccessComplexity)",
|
||||
"cvssAuthenticationr": "$enc.json($vuln.cvssAuthentication)",
|
||||
"cvssConfidentialImpact": "$enc.json($vuln.cvssConfidentialityImpact)",
|
||||
"cvssIntegrityImpact": "$enc.json($vuln.cvssIntegrityImpact)",
|
||||
"cvssAvailabilityImpact": "$enc.json($vuln.cvssAvailabilityImpact)",
|
||||
#if ($vuln.cvssScore<4.0) "severity": "Low",
|
||||
#elseif ($vuln.cvssScore>=7.0) "severity": "High",
|
||||
#else "severity": "Medium",
|
||||
#end
|
||||
"cwe": "#if ($vuln.cwe)$enc.json($vuln.cwe)#end",
|
||||
"description": "$enc.json($vuln.description)",
|
||||
"notes": "#if ($vuln.notes)$enc.json($vuln.notes)#end",
|
||||
"references": [
|
||||
#foreach($ref in $vuln.getReferences())
|
||||
#if($foreach.count > 1),#end {
|
||||
"source": "$enc.json($ref.source)",
|
||||
"url": "$enc.json($ref.url)",
|
||||
"name": "$enc.json($ref.name)"
|
||||
}#end
|
||||
],
|
||||
"vulnerableSoftware": [
|
||||
#foreach($vs in $vuln.getVulnerableSoftware())
|
||||
#if($foreach.count > 1),#end {
|
||||
"name": "$enc.json($vs.name)"
|
||||
#if($vs.hasPreviousVersion()) ,"allPreviousVersion": "true"#end
|
||||
}#end
|
||||
]
|
||||
}#end
|
||||
]#end
|
||||
}#end
|
||||
]
|
||||
}
|
||||
@@ -19,7 +19,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
@version 1.2
|
||||
|
||||
*#<?xml version="1.0"?>
|
||||
<analysis xmlns="https://jeremylong.github.io/DependencyCheck/dependency-check.1.4.xsd">
|
||||
<analysis xmlns="https://jeremylong.github.io/DependencyCheck/dependency-check.1.5.xsd">
|
||||
<scanInfo>
|
||||
<engineVersion>$version</engineVersion>
|
||||
#foreach($prop in $properties.getMetaData().entrySet())
|
||||
@@ -31,6 +31,15 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
</scanInfo>
|
||||
<projectInfo>
|
||||
<name>$enc.xml($applicationName)</name>
|
||||
#if ($groupID)
|
||||
<groupID>$enc.xml($groupID)</groupID>
|
||||
#end
|
||||
#if ($artifactID)
|
||||
<artifactID>$enc.xml($artifactID)</artifactID>
|
||||
#end
|
||||
#if ($version)
|
||||
<version>$enc.xml($version)</version>
|
||||
#end
|
||||
<reportDate>$scanDateXML</reportDate>
|
||||
<credits>This report contains data retrieved from the National Vulnerability Database: http://nvd.nist.gov</credits>
|
||||
</projectInfo>
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@@ -29,12 +30,13 @@ import org.owasp.dependencycheck.exception.ReportException;
|
||||
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
||||
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
public class EngineIntegrationTest extends BaseDBTestCase {
|
||||
public class EngineIT extends BaseDBTestCase {
|
||||
|
||||
/**
|
||||
* Test running the entire engine.
|
||||
@@ -71,12 +73,7 @@ public class EngineIntegrationTest extends BaseDBTestCase {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
DatabaseProperties prop = null;
|
||||
try (CveDB cve = CveDB.getInstance()) {
|
||||
prop = cve.getDatabaseProperties();
|
||||
}
|
||||
ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), prop);
|
||||
rg.generateReports("./target/", "ALL");
|
||||
instance.writeReports("dependency-check sample", new File("./target/"), "ALL");
|
||||
instance.cleanup();
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ import org.owasp.dependencycheck.utils.Settings;
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
public class ArchiveAnalyzerIntegrationTest extends BaseDBTestCase {
|
||||
public class ArchiveAnalyzerIT extends BaseDBTestCase {
|
||||
|
||||
/**
|
||||
* Test of getSupportedExtensions method, of class ArchiveAnalyzer.
|
||||
@@ -34,12 +34,14 @@ import org.owasp.dependencycheck.data.cpe.IndexEntry;
|
||||
import org.owasp.dependencycheck.dependency.Confidence;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
import org.owasp.dependencycheck.dependency.Identifier;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
public class CPEAnalyzerIntegrationTest extends BaseDBTestCase {
|
||||
public class CPEAnalyzerIT extends BaseDBTestCase {
|
||||
|
||||
/**
|
||||
* Tests of buildSearch of class CPEAnalyzer.
|
||||
@@ -24,7 +24,7 @@ import org.owasp.dependencycheck.BaseDBTestCase;
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
public class DependencyBundlingAnalyzerIntegrationTest extends BaseDBTestCase {
|
||||
public class DependencyBundlingAnalyzerIT extends BaseDBTestCase {
|
||||
|
||||
/**
|
||||
* Test of analyze method, of class DependencyBundlingAnalyzer.
|
||||
@@ -26,13 +26,15 @@ import org.owasp.dependencycheck.BaseTest;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Testing the vulnerability suppression analyzer.
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
public class VulnerabilitySuppressionAnalyzerIntegrationTest extends BaseDBTestCase {
|
||||
public class VulnerabilitySuppressionAnalyzerIT extends BaseDBTestCase {
|
||||
|
||||
/**
|
||||
* Test of getName method, of class VulnerabilitySuppressionAnalyzer.
|
||||
@@ -34,12 +34,27 @@ import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
public class CveDBIntegrationTest extends BaseDBTestCase {
|
||||
public class CveDBIT extends BaseDBTestCase {
|
||||
|
||||
/**
|
||||
* Pretty useless tests of open, commit, and close methods, of class CveDB.
|
||||
@@ -53,8 +68,10 @@ public class CveDBIntegrationTest extends BaseDBTestCase {
|
||||
} catch (DatabaseException | SQLException ex) {
|
||||
fail(ex.getMessage());
|
||||
} finally {
|
||||
int start = instance.getUsageCount();
|
||||
instance.close();
|
||||
assertFalse(instance.isOpen());
|
||||
int end = instance.getUsageCount();
|
||||
assertTrue( end < start);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,12 +28,14 @@ import org.junit.Test;
|
||||
import org.owasp.dependencycheck.BaseTest;
|
||||
import org.owasp.dependencycheck.dependency.Vulnerability;
|
||||
import org.owasp.dependencycheck.dependency.VulnerableSoftware;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
public class CveDBMySQLTest extends BaseTest {
|
||||
public class CveDBMySqlIT extends BaseTest {
|
||||
|
||||
/**
|
||||
* Pretty useless tests of open, commit, and close methods, of class CveDB.
|
||||
@@ -47,8 +49,10 @@ public class CveDBMySQLTest extends BaseTest {
|
||||
System.out.println("Unable to connect to the My SQL database; verify that the db server is running and that the schema has been generated");
|
||||
fail(ex.getMessage());
|
||||
} finally {
|
||||
int start = instance.getUsageCount();
|
||||
instance.close();
|
||||
assertFalse(instance.isOpen());
|
||||
int end = instance.getUsageCount();
|
||||
assertTrue( end < start);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,12 +24,15 @@ import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
import org.owasp.dependencycheck.data.update.nvd.NvdCveInfo;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
public class DatabasePropertiesIntegrationTest extends BaseDBTestCase {
|
||||
public class DatabasePropertiesIT extends BaseDBTestCase {
|
||||
|
||||
/**
|
||||
* Test of isEmpty method, of class DatabaseProperties.
|
||||
@@ -23,12 +23,14 @@ import org.junit.Test;
|
||||
import org.owasp.dependencycheck.BaseDBTestCase;
|
||||
import org.owasp.dependencycheck.data.update.exception.UpdateException;
|
||||
import org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
public class NvdCveUpdaterIntegrationTest extends BaseDBTestCase {
|
||||
public class NvdCveUpdaterIT extends BaseDBTestCase {
|
||||
|
||||
public NvdCveUpdater getUpdater() {
|
||||
NvdCveUpdater instance = new NvdCveUpdater();
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* 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) 2017 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.reporting;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
import org.owasp.dependencycheck.dependency.Identifier;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jerem
|
||||
*/
|
||||
public class EscapeToolTest {
|
||||
|
||||
/**
|
||||
* Test of url method, of class EscapeTool.
|
||||
*/
|
||||
@Test
|
||||
public void testUrl() {
|
||||
String text = null;
|
||||
EscapeTool instance = new EscapeTool();
|
||||
String expResult = null;
|
||||
String result = instance.url(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "";
|
||||
expResult = "";
|
||||
result = instance.url(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = " ";
|
||||
expResult = "+";
|
||||
result = instance.url(text);
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of html method, of class EscapeTool.
|
||||
*/
|
||||
@Test
|
||||
public void testHtml() {
|
||||
EscapeTool instance = new EscapeTool();
|
||||
String text = null;
|
||||
String expResult = null;
|
||||
String result = instance.html(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "";
|
||||
expResult = "";
|
||||
result = instance.html(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "<div>";
|
||||
expResult = "<div>";
|
||||
result = instance.html(text);
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of xml method, of class EscapeTool.
|
||||
*/
|
||||
@Test
|
||||
public void testXml() {
|
||||
EscapeTool instance = new EscapeTool();
|
||||
String text = null;
|
||||
String expResult = null;
|
||||
String result = instance.xml(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "";
|
||||
expResult = "";
|
||||
result = instance.xml(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "<div>";
|
||||
expResult = "<div>";
|
||||
result = instance.xml(text);
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of json method, of class EscapeTool.
|
||||
*/
|
||||
@Test
|
||||
public void testJson() {
|
||||
String text = null;
|
||||
EscapeTool instance = new EscapeTool();
|
||||
String expResult = null;
|
||||
String result = instance.json(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "";
|
||||
expResult = "";
|
||||
result = instance.json(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "test \"quote\"\"";
|
||||
expResult = "test \\\"quote\\\"\\\"";
|
||||
result = instance.json(text);
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of csv method, of class EscapeTool.
|
||||
*/
|
||||
@Test
|
||||
public void testCsv() {
|
||||
String text = null;
|
||||
EscapeTool instance = new EscapeTool();
|
||||
String expResult = null;
|
||||
String result = instance.csv(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "";
|
||||
expResult = "";
|
||||
result = instance.csv(text);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
text = "one, two";
|
||||
expResult = "\"one, two\"";
|
||||
result = instance.csv(text);
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of csvIdentifiers method, of class EscapeTool.
|
||||
*/
|
||||
@Test
|
||||
public void testCsvIdentifiers() {
|
||||
EscapeTool instance = new EscapeTool();
|
||||
Set<Identifier> ids = null;
|
||||
String expResult = "";
|
||||
String result = instance.csvIdentifiers(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
expResult = "";
|
||||
result = instance.csvIdentifiers(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
ids.add(new Identifier("cpe", "cpe:/a:somegroup:something:1.0", ""));
|
||||
expResult = "";
|
||||
result = instance.csvIdentifiers(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
ids.add(new Identifier("gav", "somegroup:something:1.0", ""));
|
||||
expResult = "somegroup:something:1.0";
|
||||
result = instance.csvIdentifiers(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
ids.add(new Identifier("cpe", "cpe:/a:somegroup:something:1.0", ""));
|
||||
ids.add(new Identifier("gav", "somegroup:something:1.0", ""));
|
||||
expResult = "somegroup:something:1.0";
|
||||
result = instance.csvIdentifiers(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
ids.add(new Identifier("cpe", "cpe:/a:somegroup:something:1.0", ""));
|
||||
ids.add(new Identifier("gav", "somegroup:something:1.0", ""));
|
||||
ids.add(new Identifier("gav", "somegroup2:something:1.2", ""));
|
||||
expResult = "\"somegroup:something:1.0, somegroup2:something:1.2\"";
|
||||
String expResult2 = "\"somegroup2:something:1.2, somegroup:something:1.0\"";
|
||||
result = instance.csvIdentifiers(ids);
|
||||
assertTrue(expResult.equals(result) || expResult2.equals(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of csvCpe method, of class EscapeTool.
|
||||
*/
|
||||
@Test
|
||||
public void testCsvCpe() {
|
||||
EscapeTool instance = new EscapeTool();
|
||||
Set<Identifier> ids = null;
|
||||
String expResult = "";
|
||||
String result = instance.csvCpe(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
expResult = "";
|
||||
result = instance.csvCpe(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
ids.add(new Identifier("gav", "somegroup:something:1.0", ""));
|
||||
expResult = "";
|
||||
result = instance.csvCpe(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
ids.add(new Identifier("cpe", "cpe:/a:somegroup:something:1.0", ""));
|
||||
expResult = "cpe:/a:somegroup:something:1.0";
|
||||
result = instance.csvCpe(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
ids.add(new Identifier("cpe", "cpe:/a:somegroup:something:1.0", ""));
|
||||
ids.add(new Identifier("gav", "somegroup:something:1.0", ""));
|
||||
expResult = "cpe:/a:somegroup:something:1.0";
|
||||
result = instance.csvCpe(ids);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
ids = new HashSet<>();
|
||||
ids.add(new Identifier("cpe", "cpe:/a:somegroup:something:1.0", ""));
|
||||
ids.add(new Identifier("gav", "somegroup:something:1.0", ""));
|
||||
ids.add(new Identifier("cpe", "cpe:/a:somegroup2:something:1.2", ""));
|
||||
expResult = "\"cpe:/a:somegroup:something:1.0, cpe:/a:somegroup2:something:1.2\"";
|
||||
String expResult2 = "\"cpe:/a:somegroup2:something:1.2, cpe:/a:somegroup:something:1.0\"";
|
||||
result = instance.csvCpe(ids);
|
||||
assertTrue(expResult.equals(result) || expResult2.equals(result));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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) 2012 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.reporting;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
import javax.xml.validation.Validator;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.owasp.dependencycheck.BaseDBTestCase;
|
||||
import org.owasp.dependencycheck.BaseTest;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||
import org.owasp.dependencycheck.exception.ExceptionCollection;
|
||||
import org.owasp.dependencycheck.exception.ReportException;
|
||||
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
import org.xml.sax.SAXException;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
public class ReportGeneratorIT extends BaseDBTestCase {
|
||||
|
||||
/**
|
||||
* Generates an XML report containing known vulnerabilities and realistic
|
||||
* data and validates the generated XML document against the XSD.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testGenerateReport() {
|
||||
try {
|
||||
String templateName = "XmlReport";
|
||||
|
||||
File f = new File("target/test-reports");
|
||||
if (!f.exists()) {
|
||||
f.mkdir();
|
||||
}
|
||||
File writeTo = new File("target/test-reports/Report.xml");
|
||||
File suppressionFile = BaseTest.getResourceAsFile(this, "incorrectSuppressions.xml");
|
||||
|
||||
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile.getAbsolutePath());
|
||||
|
||||
//File struts = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath());
|
||||
File struts = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar");
|
||||
//File axis = new File(this.getClass().getClassLoader().getResource("axis2-adb-1.4.1.jar").getPath());
|
||||
File axis = BaseTest.getResourceAsFile(this, "axis2-adb-1.4.1.jar");
|
||||
//File jetty = new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath());
|
||||
File jetty = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar");
|
||||
|
||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
|
||||
Engine engine = new Engine();
|
||||
|
||||
engine.scan(struts);
|
||||
engine.scan(axis);
|
||||
engine.scan(jetty);
|
||||
engine.analyzeDependencies();
|
||||
engine.writeReports("Test Report", "org.owasp", "dependency-check-core", "1.4.7", writeTo, "XML");
|
||||
|
||||
engine.cleanup();
|
||||
|
||||
InputStream xsdStream = ReportGenerator.class.getClassLoader().getResourceAsStream("schema/dependency-check.1.5.xsd");
|
||||
StreamSource xsdSource = new StreamSource(xsdStream);
|
||||
StreamSource xmlSource = new StreamSource(writeTo);
|
||||
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||
Schema schema = sf.newSchema(xsdSource);
|
||||
Validator validator = schema.newValidator();
|
||||
validator.validate(xmlSource);
|
||||
} catch (InvalidSettingException ex) {
|
||||
fail(ex.getMessage());
|
||||
} catch (DatabaseException | ExceptionCollection | ReportException | SAXException | IOException ex) {
|
||||
fail(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
* 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) 2012 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.reporting;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
import javax.xml.validation.Validator;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.owasp.dependencycheck.BaseDBTestCase;
|
||||
import org.owasp.dependencycheck.BaseTest;
|
||||
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.exception.ExceptionCollection;
|
||||
import org.owasp.dependencycheck.exception.ReportException;
|
||||
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
public class ReportGeneratorIntegrationTest extends BaseDBTestCase {
|
||||
|
||||
/**
|
||||
* Test of generateReport method, of class ReportGenerator.
|
||||
*
|
||||
* @throws Exception is thrown when an exception occurs.
|
||||
*/
|
||||
@Test
|
||||
public void testGenerateReport() throws Exception {
|
||||
// String templateName = "HtmlReport";
|
||||
// File f = new File("target/test-reports");
|
||||
// if (!f.exists()) {
|
||||
// f.mkdir();
|
||||
// }
|
||||
// String writeTo = "target/test-reports/Report.html";
|
||||
// Map<String, Object> properties = new HashMap<String, Object>();
|
||||
// Dependency d = new Dependency();
|
||||
// d.setFileName("FileName.jar");
|
||||
// d.setActualFilePath("lib/FileName.jar");
|
||||
// d.addCPEentry("cpe://a:/some:cpe:1.0");
|
||||
//
|
||||
// List<Dependency> dependencies = new ArrayList<Dependency>();
|
||||
// d.getProductEvidence().addEvidence("jar","filename","<test>test", Confidence.HIGH);
|
||||
// d.getProductEvidence().addEvidence("manifest","vendor","<test>test", Confidence.HIGH);
|
||||
//
|
||||
// for (Evidence e : d.getProductEvidence().iterator(Confidence.HIGH)) {
|
||||
// String t = e.getValue();
|
||||
// }
|
||||
// dependencies.add(d);
|
||||
//
|
||||
// Dependency d2 = new Dependency();
|
||||
// d2.setFileName("Another.jar");
|
||||
// d2.setActualFilePath("lib/Another.jar");
|
||||
// d2.addCPEentry("cpe://a:/another:cpe:1.0");
|
||||
// d2.addCPEentry("cpe://a:/another:cpe:1.1");
|
||||
// d2.addCPEentry("cpe://a:/another:cpe:1.2");
|
||||
// d2.getProductEvidence().addEvidence("jar","filename","another.jar", Confidence.HIGH);
|
||||
// d2.getProductEvidence().addEvidence("manifest","vendor","Company A", Confidence.MEDIUM);
|
||||
//
|
||||
// for (Evidence e : d2.getProductEvidence().iterator(Confidence.HIGH)) {
|
||||
// String t = e.getValue();
|
||||
// }
|
||||
//
|
||||
// dependencies.add(d2);
|
||||
//
|
||||
// Dependency d3 = new Dependency();
|
||||
// d3.setFileName("Third.jar");
|
||||
// d3.setActualFilePath("lib/Third.jar");
|
||||
// d3.getProductEvidence().addEvidence("jar","filename","third.jar", Confidence.HIGH);
|
||||
//
|
||||
// for (Evidence e : d3.getProductEvidence().iterator(Confidence.HIGH)) {
|
||||
// String t = e.getValue();
|
||||
// }
|
||||
//
|
||||
// dependencies.add(d3);
|
||||
//
|
||||
// properties.put("dependencies",dependencies);
|
||||
//
|
||||
// ReportGenerator instance = new ReportGenerator();
|
||||
// instance.generateReport(templateName, writeTo, properties);
|
||||
//assertTrue("need to add a real check here", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an XML report containing known vulnerabilities and realistic data and validates the generated XML document
|
||||
* against the XSD.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testGenerateXMLReport() {
|
||||
try {
|
||||
String templateName = "XmlReport";
|
||||
|
||||
File f = new File("target/test-reports");
|
||||
if (!f.exists()) {
|
||||
f.mkdir();
|
||||
}
|
||||
String writeTo = "target/test-reports/Report.xml";
|
||||
File suppressionFile = BaseTest.getResourceAsFile(this, "incorrectSuppressions.xml");
|
||||
|
||||
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile.getAbsolutePath());
|
||||
|
||||
//File struts = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath());
|
||||
File struts = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar");
|
||||
//File axis = new File(this.getClass().getClassLoader().getResource("axis2-adb-1.4.1.jar").getPath());
|
||||
File axis = BaseTest.getResourceAsFile(this, "axis2-adb-1.4.1.jar");
|
||||
//File jetty = new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath());
|
||||
File jetty = BaseTest.getResourceAsFile(this, "org.mortbay.jetty.jar");
|
||||
|
||||
boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
|
||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
|
||||
Engine engine = new Engine();
|
||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
|
||||
|
||||
engine.scan(struts);
|
||||
engine.scan(axis);
|
||||
engine.scan(jetty);
|
||||
engine.analyzeDependencies();
|
||||
|
||||
CveDB cveDB = CveDB.getInstance();
|
||||
DatabaseProperties dbProp = cveDB.getDatabaseProperties();
|
||||
|
||||
ReportGenerator generator = new ReportGenerator("Test Report", engine.getDependencies(), engine.getAnalyzers(), dbProp);
|
||||
generator.generateReport(templateName, writeTo);
|
||||
cveDB.close();
|
||||
|
||||
engine.cleanup();
|
||||
|
||||
InputStream xsdStream = ReportGenerator.class.getClassLoader().getResourceAsStream("schema/dependency-check.1.4.xsd");
|
||||
StreamSource xsdSource = new StreamSource(xsdStream);
|
||||
StreamSource xmlSource = new StreamSource(new File(writeTo));
|
||||
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||
Schema schema = sf.newSchema(xsdSource);
|
||||
Validator validator = schema.newValidator();
|
||||
validator.validate(xmlSource);
|
||||
} catch (InvalidSettingException ex) {
|
||||
fail(ex.getMessage());
|
||||
} catch (DatabaseException | ExceptionCollection | ReportException | SAXException | IOException ex) {
|
||||
fail(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ data.password=DC-Pass1337!
|
||||
data.driver_name=org.h2.Driver
|
||||
data.driver_path=
|
||||
|
||||
proxy.disableSchemas=true
|
||||
# the number of days that the modified nvd cve data holds data for. We don't need
|
||||
# to update the other files if we are within this timespan. Per NIST this file
|
||||
# holds 8 days of updates, we are using 7 just to be safe.
|
||||
|
||||
@@ -85,23 +85,6 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>-Dfile.encoding=UTF-8</argLine>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>data.directory</name>
|
||||
<value>${project.build.directory}/dependency-check-data</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>temp.directory</name>
|
||||
<value>${project.build.directory}/temp</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<inherited>true</inherited>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@@ -244,6 +227,13 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-invoker-plugin</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<version>2.4.11</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
<!--streamLogs>true</streamLogs-->
|
||||
<!-- The parallel builds cannot be increased beyond 2 as 690 must run before others (can be run parralel to 618 though) -->
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# This file is part of dependency-check-maven.
|
||||
#
|
||||
# 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) 2017 Jeremy Long. All Rights Reserved.
|
||||
#
|
||||
|
||||
invoker.goals = install ${project.groupId}:${project.artifactId}:${project.version}:check -e -Dformat=JSON
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
This file is part of dependency-check-maven.
|
||||
|
||||
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) 2017 Jeremy Long. All Rights Reserved.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.owasp.test</groupId>
|
||||
<artifactId>test-system-scope</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<scope>system</scope>
|
||||
<groupId>com.sun</groupId>
|
||||
<artifactId>tools</artifactId>
|
||||
<version>1.8</version>
|
||||
<systemPath>${java.home}/../lib/tools.jar</systemPath>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This file is part of dependency-check-maven.
|
||||
*
|
||||
* 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) 2017 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import java.nio.charset.Charset;
|
||||
import groovy.json.JsonSlurper;
|
||||
|
||||
def slurper = new JsonSlurper()
|
||||
def json = slurper.parse(new File(basedir, "target/dependency-check-report.json"), "UTF-8")
|
||||
|
||||
assert json instanceof Map
|
||||
assert json.dependencies instanceof List
|
||||
assert json.dependencies.size()==1
|
||||
return true;
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* This file is part of dependency-check-maven.
|
||||
*
|
||||
* 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) 2017 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# This file is part of dependency-check-maven.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
invoker.goals = install ${project.groupId}:${project.artifactId}:${project.version}:check -DskipSystemScope=true -Dformat=JSON
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
This file is part of dependency-check-maven.
|
||||
|
||||
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) 2017 Jeremy Long. All Rights Reserved.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.owasp.test</groupId>
|
||||
<artifactId>test-system-scope</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<scope>system</scope>
|
||||
<groupId>com.sun</groupId>
|
||||
<artifactId>tools</artifactId>
|
||||
<version>1.8</version>
|
||||
<systemPath>${java.home}/../lib/tools.jar</systemPath>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This file is part of dependency-check-maven.
|
||||
*
|
||||
* 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) 2017 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import java.nio.charset.Charset;
|
||||
import groovy.json.JsonSlurper;
|
||||
|
||||
def slurper = new JsonSlurper()
|
||||
def json = slurper.parse(new File(basedir, "target/dependency-check-report.json"), "UTF-8")
|
||||
|
||||
assert json instanceof Map
|
||||
assert json.dependencies instanceof List
|
||||
assert json.dependencies.size()==0
|
||||
return true;
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* This file is part of dependency-check-maven.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
@@ -22,6 +22,19 @@ Copyright (c) 2017 Jeremy Long. All Rights Reserved.
|
||||
<artifactId>test-dataformat-jackson</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>redhat</id>
|
||||
<name>redhat</name>
|
||||
<url>https://maven.repository.redhat.com/ga/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring</id>
|
||||
<name>spring</name>
|
||||
<url>http://repo.spring.io/plugins-release/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!-- False Positives from issue #642 -->
|
||||
<dependency>
|
||||
@@ -29,6 +42,37 @@ Copyright (c) 2017 Jeremy Long. All Rights Reserved.
|
||||
<artifactId>spring-boot</artifactId>
|
||||
<version>1.4.3.RELEASE</version>
|
||||
</dependency>
|
||||
<!-- end issue #642 -->
|
||||
<!-- End Issue #642 -->
|
||||
<!-- False Positives from issue #699 -->
|
||||
<dependency>
|
||||
<groupId>com.splunk</groupId>
|
||||
<artifactId>splunk</artifactId>
|
||||
<version>1.6.2.0</version>
|
||||
</dependency>
|
||||
<!-- End Issue #699 -->
|
||||
<!-- False Positives from issue #700 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-core</artifactId>
|
||||
<version>1.2.5.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
<version>1.1.7.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-context</artifactId>
|
||||
<version>1.1.7.RELEASE</version>
|
||||
</dependency>
|
||||
<!-- End Issue #700 -->
|
||||
<!-- False Positives from issue #713 -->
|
||||
<dependency>
|
||||
<groupId>org.openid4java</groupId>
|
||||
<artifactId>openid4java</artifactId>
|
||||
<version>0.9.7</version>
|
||||
</dependency>
|
||||
<!-- End Issue #713 -->
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -20,16 +20,6 @@ import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
// Save NVD-CVE for next IT (if not already done)
|
||||
File datasDwl = new File("target/local-repo/org/owasp/dependency-check-data/3.0", "dc.h2.db");
|
||||
File datasSave = new File("target/nvd-cve-backup", "dc.h2.db");
|
||||
if (datasDwl.exists() && !datasSave.exists()){
|
||||
System.out.println("Save NVD-CVE into backup");
|
||||
FileUtils.copyFile(datasDwl, datasSave);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Check to see if jackson-dataformat-xml-2.4.5.jar was identified.
|
||||
//TODO change this to xpath and check for CVE-2016-3720
|
||||
|
||||
@@ -123,7 +123,8 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
||||
outputDir = new File(this.getProject().getBuild().getDirectory());
|
||||
}
|
||||
try {
|
||||
writeReports(engine, this.getProject(), outputDir);
|
||||
final MavenProject p = this.getProject();
|
||||
engine.writeReports(p.getName(), p.getGroupId(), p.getArtifactId(), p.getVersion(), outputDir, getFormat());
|
||||
} catch (ReportException ex) {
|
||||
if (exCol == null) {
|
||||
exCol = new ExceptionCollection("Error writing aggregate report", ex);
|
||||
|
||||
@@ -55,6 +55,7 @@ import org.owasp.dependencycheck.dependency.Confidence;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
import org.owasp.dependencycheck.dependency.Identifier;
|
||||
import org.owasp.dependencycheck.dependency.Vulnerability;
|
||||
import org.owasp.dependencycheck.exception.DependencyNotFoundException;
|
||||
import org.owasp.dependencycheck.exception.ExceptionCollection;
|
||||
import org.owasp.dependencycheck.exception.ReportException;
|
||||
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
||||
@@ -117,7 +118,7 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
* The Maven Session.
|
||||
*/
|
||||
@Parameter(defaultValue = "${session}", readonly = true, required = true)
|
||||
protected MavenSession session;
|
||||
private MavenSession session;
|
||||
|
||||
/**
|
||||
* Remote repositories which will be searched for artifacts.
|
||||
@@ -403,6 +404,13 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
@SuppressWarnings("CanBeFinal")
|
||||
@Parameter(property = "skipProvidedScope", defaultValue = "false", required = false)
|
||||
private boolean skipProvidedScope = false;
|
||||
|
||||
/**
|
||||
* Skip Analysis for Provided Scope Dependencies.
|
||||
*/
|
||||
@SuppressWarnings("CanBeFinal")
|
||||
@Parameter(property = "skipSystemScope", defaultValue = "false", required = false)
|
||||
private boolean skipSystemScope = false;
|
||||
/**
|
||||
* The data directory, hold DC SQL DB.
|
||||
*/
|
||||
@@ -627,24 +635,54 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
* @return a collection of exceptions that may have occurred while resolving
|
||||
* and scanning the dependencies
|
||||
*/
|
||||
private ExceptionCollection collectDependencies(Engine engine, MavenProject project, List<DependencyNode> nodes, ProjectBuildingRequest buildingRequest) {
|
||||
private ExceptionCollection collectDependencies(Engine engine, MavenProject project,
|
||||
List<DependencyNode> nodes, ProjectBuildingRequest buildingRequest) {
|
||||
ExceptionCollection exCol = null;
|
||||
for (DependencyNode dependencyNode : nodes) {
|
||||
exCol = collectDependencies(engine, project, dependencyNode.getChildren(), buildingRequest);
|
||||
if (excludeFromScan(dependencyNode.getArtifact().getScope())) {
|
||||
continue;
|
||||
}
|
||||
exCol = collectDependencies(engine, project, dependencyNode.getChildren(), buildingRequest);
|
||||
try {
|
||||
final ArtifactCoordinate coordinate = TransferUtils.toArtifactCoordinate(dependencyNode.getArtifact());
|
||||
final Artifact result = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact();
|
||||
if (result.isResolved() && result.getFile() != null) {
|
||||
final List<Dependency> deps = engine.scan(result.getFile().getAbsoluteFile(),
|
||||
boolean isResolved = false;
|
||||
File artifactFile = null;
|
||||
String artifactId = null;
|
||||
String groupId = null;
|
||||
String version = null;
|
||||
if (org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals(dependencyNode.getArtifact().getScope())) {
|
||||
for (org.apache.maven.model.Dependency d : project.getDependencies()) {
|
||||
Artifact a = dependencyNode.getArtifact();
|
||||
if (d.getSystemPath() != null && artifactsMatch(d, a)) {
|
||||
|
||||
artifactFile = new File(d.getSystemPath());
|
||||
isResolved = artifactFile.isFile();
|
||||
groupId = a.getGroupId();
|
||||
artifactId = a.getArtifactId();
|
||||
version = a.getVersion();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isResolved) {
|
||||
getLog().error("Unable to resolve system scoped dependency: " + dependencyNode.toNodeString());
|
||||
exCol.addException(new DependencyNotFoundException("Unable to resolve system scoped dependency: " + dependencyNode.toNodeString()));
|
||||
}
|
||||
} else {
|
||||
final ArtifactCoordinate coordinate = TransferUtils.toArtifactCoordinate(dependencyNode.getArtifact());
|
||||
final Artifact result = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact();
|
||||
isResolved = result.isResolved();
|
||||
artifactFile = result.getFile();
|
||||
groupId = result.getGroupId();
|
||||
artifactId = result.getArtifactId();
|
||||
version = result.getVersion();
|
||||
}
|
||||
if (isResolved && artifactFile != null) {
|
||||
final List<Dependency> deps = engine.scan(artifactFile.getAbsoluteFile(),
|
||||
project.getName() + ":" + dependencyNode.getArtifact().getScope());
|
||||
if (deps != null) {
|
||||
if (deps.size() == 1) {
|
||||
final Dependency d = deps.get(0);
|
||||
if (d != null) {
|
||||
final MavenArtifact ma = new MavenArtifact(result.getGroupId(), result.getArtifactId(), result.getVersion());
|
||||
final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version);
|
||||
d.addAsEvidence("pom", ma, Confidence.HIGHEST);
|
||||
if (getLog().isDebugEnabled()) {
|
||||
getLog().debug(String.format("Adding project reference %s on dependency %s",
|
||||
@@ -682,6 +720,33 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
return exCol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the groupId, artifactId, and version of the Maven
|
||||
* dependency and artifact match.
|
||||
*
|
||||
* @param d the Maven dependency
|
||||
* @param a the Maven artifact
|
||||
* @return true if the groupId, artifactId, and version match
|
||||
*/
|
||||
private static boolean artifactsMatch(org.apache.maven.model.Dependency d, Artifact a) {
|
||||
return (isEqualOrNull(a.getArtifactId(), d.getArtifactId()))
|
||||
&& (isEqualOrNull(a.getGroupId(), d.getGroupId()))
|
||||
&& (isEqualOrNull(a.getVersion(), d.getVersion()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two strings for equality; if both strings are null they are
|
||||
* considered equal.
|
||||
*
|
||||
* @param left the first string to compare
|
||||
* @param right the second string to compare
|
||||
* @return true if the strings are equal or if they are both null; otherwise
|
||||
* false.
|
||||
*/
|
||||
private static boolean isEqualOrNull(String left, String right) {
|
||||
return (left != null && left.equals(right)) || (left == null && right == null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns a new ProjectBuildingRequest populated from the current
|
||||
* session and the current project remote repositories, used to resolve
|
||||
@@ -756,6 +821,10 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
return "dependency-check-report.xml#";
|
||||
} else if ("VULN".equalsIgnoreCase(this.format)) {
|
||||
return "dependency-check-vulnerability";
|
||||
} else if ("JSON".equalsIgnoreCase(this.format)) {
|
||||
return "dependency-check-report.json";
|
||||
} else if ("CSV".equalsIgnoreCase(this.format)) {
|
||||
return "dependency-check-report.csv";
|
||||
} else {
|
||||
getLog().warn("Unknown report format used during site generation.");
|
||||
return "dependency-check-report";
|
||||
@@ -962,6 +1031,9 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
if (skipProvidedScope && org.apache.maven.artifact.Artifact.SCOPE_PROVIDED.equals(scope)) {
|
||||
return true;
|
||||
}
|
||||
if (skipSystemScope && org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals(scope)) {
|
||||
return true;
|
||||
}
|
||||
return skipRuntimeScope && !org.apache.maven.artifact.Artifact.SCOPE_RUNTIME.equals(scope);
|
||||
}
|
||||
|
||||
@@ -997,34 +1069,6 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the reports for a given dependency-check engine.
|
||||
*
|
||||
* @param engine a dependency-check engine
|
||||
* @param p the Maven project
|
||||
* @param outputDir the directory path to write the report(s)
|
||||
* @throws ReportException thrown if there is an error writing the report
|
||||
*/
|
||||
protected void writeReports(Engine engine, MavenProject p, File outputDir) throws ReportException {
|
||||
DatabaseProperties prop = null;
|
||||
try (CveDB cve = CveDB.getInstance()) {
|
||||
prop = cve.getDatabaseProperties();
|
||||
} catch (DatabaseException ex) {
|
||||
//TODO shouldn't this throw an exception?
|
||||
if (getLog().isDebugEnabled()) {
|
||||
getLog().debug("Unable to retrieve DB Properties", ex);
|
||||
}
|
||||
}
|
||||
final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop);
|
||||
try {
|
||||
r.generateReports(outputDir.getAbsolutePath(), format);
|
||||
} catch (ReportException ex) {
|
||||
final String msg = String.format("Error generating the report for %s", p.getName());
|
||||
throw new ReportException(msg, ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc="Methods to fail build or show summary">
|
||||
/**
|
||||
* Checks to see if a vulnerability has been identified with a CVSS score
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.apache.maven.plugins.annotations.ResolutionScope;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||
import org.owasp.dependencycheck.exception.ExceptionCollection;
|
||||
@@ -99,33 +100,32 @@ public class CheckMojo extends BaseDependencyCheckMojo {
|
||||
ExceptionCollection exCol = scanArtifacts(getProject(), engine);
|
||||
if (engine.getDependencies().isEmpty()) {
|
||||
getLog().info("No dependencies were identified that could be analyzed by dependency-check");
|
||||
} else {
|
||||
try {
|
||||
engine.analyzeDependencies();
|
||||
} catch (ExceptionCollection ex) {
|
||||
if (this.isFailOnError() && ex.isFatal()) {
|
||||
throw new MojoExecutionException("One or more exceptions occurred during analysis", ex);
|
||||
}
|
||||
exCol = ex;
|
||||
}
|
||||
try {
|
||||
engine.analyzeDependencies();
|
||||
} catch (ExceptionCollection ex) {
|
||||
if (this.isFailOnError() && ex.isFatal()) {
|
||||
throw new MojoExecutionException("One or more exceptions occurred during analysis", ex);
|
||||
}
|
||||
if (exCol == null || !exCol.isFatal()) {
|
||||
try {
|
||||
writeReports(engine, getProject(), getCorrectOutputDirectory());
|
||||
} catch (ReportException ex) {
|
||||
if (this.isFailOnError()) {
|
||||
if (exCol != null) {
|
||||
exCol.addException(ex);
|
||||
} else {
|
||||
exCol = new ExceptionCollection("Unable to write the dependency-check report", ex);
|
||||
}
|
||||
exCol = ex;
|
||||
}
|
||||
if (exCol == null || !exCol.isFatal()) {
|
||||
try {
|
||||
final MavenProject p = this.getProject();
|
||||
engine.writeReports(p.getName(), p.getGroupId(), p.getArtifactId(), p.getVersion(), getCorrectOutputDirectory(), getFormat());
|
||||
} catch (ReportException ex) {
|
||||
if (this.isFailOnError()) {
|
||||
if (exCol != null) {
|
||||
exCol.addException(ex);
|
||||
} else {
|
||||
exCol = new ExceptionCollection("Unable to write the dependency-check report", ex);
|
||||
}
|
||||
}
|
||||
//writeDataFile(getProject(), null, engine.getDependencies());
|
||||
showSummary(getProject(), engine.getDependencies());
|
||||
checkForFailure(engine.getDependencies());
|
||||
if (exCol != null && this.isFailOnError()) {
|
||||
throw new MojoExecutionException("One or more exceptions occurred during dependency-check analysis", exCol);
|
||||
}
|
||||
}
|
||||
showSummary(getProject(), engine.getDependencies());
|
||||
checkForFailure(engine.getDependencies());
|
||||
if (exCol != null && this.isFailOnError()) {
|
||||
throw new MojoExecutionException("One or more exceptions occurred during dependency-check analysis", exCol);
|
||||
}
|
||||
}
|
||||
engine.cleanup();
|
||||
|
||||
@@ -19,13 +19,14 @@ cveValidForHours | Sets the number of hours to wait before checking f
|
||||
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
|
||||
failBuildOnAnyVulnerability | Specific that if any vulnerability is identified, the build will fail. | false
|
||||
failOnError | Whether the build should fail if there is an error executing the dependency-check analysis. | true
|
||||
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, CSV, JSON, VULN, ALL). This configuration option has no affect if using this within the Site plugin unless the externalReport is set to true. | HTML
|
||||
name | The name of the report in the site. | dependency-check or dependency-check:aggregate
|
||||
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'
|
||||
skip | Skips the dependency-check analysis. | false
|
||||
skipTestScope | Skip analysis for artifacts with Test Scope. | true
|
||||
skipProvidedScope | Skip analysis for artifacts with Provided Scope. | false
|
||||
skipRuntimeScope | Skip analysis for artifacts with Runtime Scope. | false
|
||||
skipSystemScope | Skip analysis for artifacts with System Scope. | false
|
||||
skipTestScope | Skip analysis for artifacts with Test Scope. | true
|
||||
suppressionFile | The file path to the XML suppression file \- used to suppress [false positives](../general/suppression.html). |
|
||||
hintsFile | The file path to the XML hints file \- used to resolve [false negatives](../general/hints.html). |
|
||||
enableExperimental | Enable the [experimental analyzers](../analyzers/index.html). If not enabled the experimental analyzers (see below) will not be loaded or used. | false
|
||||
|
||||
@@ -41,62 +41,7 @@ Copyright (c) 2014 - Jeremy Long. All Rights Reserved.
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<!--instrumentation>
|
||||
<ignoreTrivial>true</ignoreTrivial>
|
||||
</instrumentation-->
|
||||
<check>
|
||||
<branchRate>85</branchRate>
|
||||
<lineRate>85</lineRate>
|
||||
<haltOnFailure>false</haltOnFailure>
|
||||
<totalBranchRate>85</totalBranchRate>
|
||||
<totalLineRate>85</totalLineRate>
|
||||
<packageLineRate>85</packageLineRate>
|
||||
<packageBranchRate>85</packageBranchRate>
|
||||
<regexes>
|
||||
<regex>
|
||||
<pattern>.*\$.*</pattern>
|
||||
<branchRate>0</branchRate>
|
||||
<lineRate>0</lineRate>
|
||||
</regex>
|
||||
</regexes>
|
||||
</check>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>-Dfile.encoding=UTF-8</argLine>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>data.directory</name>
|
||||
<value>${project.build.directory}/data</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>temp.directory</name>
|
||||
<value>${project.build.directory}/temp</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
<excludes>
|
||||
<exclude>**/*IntegrationTest.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
<reporting>
|
||||
|
||||
@@ -185,6 +185,12 @@ public final class Settings {
|
||||
* The properties key for the URL to retrieve the CPE.
|
||||
*/
|
||||
public static final String CPE_URL = "cpe.url";
|
||||
/**
|
||||
* Whether or not if using basic auth with a proxy the system setting
|
||||
* 'jdk.http.auth.tunneling.disabledSchemes' should be set to an empty
|
||||
* string.
|
||||
*/
|
||||
public static final String PROXY_DISABLE_SCHEMAS = "proxy.disableSchemas";
|
||||
/**
|
||||
* The properties key for the proxy server.
|
||||
*
|
||||
|
||||
@@ -67,12 +67,12 @@ public final class URLConnectionFactory {
|
||||
@SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE", justification = "Just being extra safe")
|
||||
public static HttpURLConnection createHttpURLConnection(URL url) throws URLConnectionFailureException {
|
||||
HttpURLConnection conn = null;
|
||||
final String proxyUrl = Settings.getString(Settings.KEYS.PROXY_SERVER);
|
||||
final String proxyHost = Settings.getString(Settings.KEYS.PROXY_SERVER);
|
||||
|
||||
try {
|
||||
if (proxyUrl != null && !matchNonProxy(url)) {
|
||||
if (proxyHost != null && !matchNonProxy(url)) {
|
||||
final int proxyPort = Settings.getInt(Settings.KEYS.PROXY_PORT);
|
||||
final SocketAddress address = new InetSocketAddress(proxyUrl, proxyPort);
|
||||
final SocketAddress address = new InetSocketAddress(proxyHost, proxyPort);
|
||||
|
||||
final String username = Settings.getString(Settings.KEYS.PROXY_USERNAME);
|
||||
final String password = Settings.getString(Settings.KEYS.PROXY_PASSWORD);
|
||||
@@ -81,7 +81,15 @@ public final class URLConnectionFactory {
|
||||
final Authenticator auth = new Authenticator() {
|
||||
@Override
|
||||
public PasswordAuthentication getPasswordAuthentication() {
|
||||
if (getRequestorType().equals(Authenticator.RequestorType.PROXY)) {
|
||||
if (proxyHost.equals(getRequestingHost()) || getRequestorType().equals(Authenticator.RequestorType.PROXY)) {
|
||||
LOGGER.debug("Using the configured proxy username and password");
|
||||
try {
|
||||
if (Settings.getBoolean(Settings.KEYS.PROXY_DISABLE_SCHEMAS, true)) {
|
||||
System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
|
||||
}
|
||||
} catch (InvalidSettingException ex) {
|
||||
LOGGER.trace("This exception can be ignored", ex);
|
||||
}
|
||||
return new PasswordAuthentication(username, password.toCharArray());
|
||||
}
|
||||
return super.getPasswordAuthentication();
|
||||
|
||||
@@ -21,12 +21,13 @@ import java.io.File;
|
||||
import java.net.URL;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
public class DownloaderIntegrationTest extends BaseTest {
|
||||
public class DownloaderIT extends BaseTest {
|
||||
|
||||
/**
|
||||
* Test of fetchFile method, of class Downloader.
|
||||
@@ -36,6 +36,7 @@ data.password=DC-Pass1337!
|
||||
data.driver_name=org.h2.Driver
|
||||
data.driver_path=
|
||||
|
||||
proxy.disableSchemas=true
|
||||
# the path to the cpe xml file
|
||||
cpe.url=http://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.2.xml.gz
|
||||
# the path to the cpe meta data file.
|
||||
|
||||
97
pom.xml
97
pom.xml
@@ -30,6 +30,7 @@ Copyright (c) 2012 - Jeremy Long
|
||||
<module>dependency-check-maven</module>
|
||||
<module>dependency-check-utils</module>
|
||||
<module>dependency-check-plugin</module>
|
||||
<module>build-reporting</module>
|
||||
</modules>
|
||||
<name>Dependency-Check</name>
|
||||
<url>https://github.com/jeremylong/DependencyCheck.git</url>
|
||||
@@ -132,7 +133,6 @@ Copyright (c) 2012 - Jeremy Long
|
||||
<!-- Note that Maven will use classes from the distro, ignoring declared dependencies for Maven core... -->
|
||||
<maven.api.version>3.0</maven.api.version>
|
||||
<reporting.checkstyle-plugin.version>2.17</reporting.checkstyle-plugin.version>
|
||||
<reporting.cobertura-plugin.version>2.7</reporting.cobertura-plugin.version>
|
||||
<reporting.pmd-plugin.version>3.6</reporting.pmd-plugin.version>
|
||||
</properties>
|
||||
<distributionManagement>
|
||||
@@ -162,9 +162,9 @@ Copyright (c) 2012 - Jeremy Long
|
||||
<version>1.10</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<version>2.7</version>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.7.9</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@@ -278,19 +278,83 @@ Copyright (c) 2012 - Jeremy Long
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>pre-unit-test</id>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
|
||||
<propertyName>surefireArgLine</propertyName>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>pre-integration-test</id>
|
||||
<phase>pre-integration-test</phase>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<destFile>${project.build.directory}/coverage-reports/jacoco-it.exec</destFile>
|
||||
<propertyName>failsafeArgLine</propertyName>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.gmaven</groupId>
|
||||
<artifactId>gmaven-plugin</artifactId>
|
||||
<version>1.5</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-dynamic-properties</id>
|
||||
<phase>pre-integration-test</phase>
|
||||
<goals>
|
||||
<goal>execute</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<source>
|
||||
project.properties['invoker.mavenOpts']=project.properties.failsafeArgLine
|
||||
</source>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>${surefireArgLine} -Dfile.encoding=UTF-8</argLine>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>data.directory</name>
|
||||
<value>${project.build.directory}/data</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>temp.directory</name>
|
||||
<value>${project.build.directory}/temp</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>${failsafeArgLine}</argLine>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>temp.directory</name>
|
||||
<value>${project.build.directory}/temp</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
<includes>
|
||||
<include>**/*IntegrationTest.java</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/*MySqlIT.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
@@ -529,13 +593,19 @@ Copyright (c) 2012 - Jeremy Long
|
||||
</reportSets>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<version>${reporting.cobertura-plugin.version}</version>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.7.9</version>
|
||||
<configuration>
|
||||
<dataFileIncludes>
|
||||
<dataFileInclude>target/coverage-reports/jacoco-ut.exec</dataFileInclude>
|
||||
<dataFileInclude>target/coverage-reports/jacoco-it.exec</dataFileInclude>
|
||||
</dataFileIncludes>
|
||||
</configuration>
|
||||
<reportSets>
|
||||
<reportSet>
|
||||
<reports>
|
||||
<report>cobertura</report>
|
||||
<report>report-aggregate</report>
|
||||
</reports>
|
||||
</reportSet>
|
||||
</reportSets>
|
||||
@@ -597,6 +667,11 @@ Copyright (c) 2012 - Jeremy Long
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>3.0.1u2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.3.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
|
||||
@@ -20,8 +20,8 @@ To setup a centralized database the following generalized steps can be used:
|
||||
<ol><li>Create the database and tables using either <a href="https://github.com/jeremylong/DependencyCheck/blob/master/dependency-check-core/src/main/resources/data/initialize.sql">initialize.sql</a>
|
||||
or one of the other initialization scripts <a href="https://github.com/jeremylong/DependencyCheck/tree/master/dependency-check-core/src/main/resources/data">found here</a>.</li>
|
||||
<li>The account that the clients will connect using must have select granted on the tables.
|
||||
<ul><li>Note, if the clients performing the scans should run with the noupdate setting. A single
|
||||
instance of the dependency-check client should be setup with update enabled and the account
|
||||
<ul><li>Note, the clients performing the scans should run with the noupdate setting. A single
|
||||
instance of the dependency-check client should be setup with updates enabled and the account
|
||||
used during the update process will need to be granted update rights on the tables.
|
||||
</li></ul>
|
||||
</li><li>Dependency-check clients running scans will need to be configured to use the central database:
|
||||
|
||||
@@ -17,7 +17,7 @@ autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is ena
|
||||
cveValidForHours | Sets the number of hours to wait before checking for new updates from the NVD. | 4
|
||||
failOnError | Fails the build if an error occurs during the dependency-check analysis. | true
|
||||
failBuildOnCVSS | Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11; 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). | HTML
|
||||
format | The report format to be generated (HTML, XML, CSV, JSON, VULN, ALL). | HTML
|
||||
outputDirectory | The location to write the report(s). This directory will be located in the build directory. | build/reports
|
||||
skipTestGroups | When set to true (the default) all dependency groups that being with 'test' will be skipped. | true
|
||||
suppressionFile | The file path to the XML suppression file \- used to suppress [false positives](../general/suppression.html) |
|
||||
|
||||
2
src/site/markdown/jacoco-aggregate/index.md
Normal file
2
src/site/markdown/jacoco-aggregate/index.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# Jacoco Aggregate Report
|
||||
The test coverage reports can be found [here](../build-reporting/jacoco-aggregate/index.html).
|
||||
Reference in New Issue
Block a user