mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-01-14 07:43:40 +01:00
Merge branch 'master' of github.com:jeremylong/DependencyCheck into stevespringett-master
This commit is contained in:
23
.travis.yml
23
.travis.yml
@@ -3,11 +3,22 @@ jdk: oraclejdk7
|
||||
script: mvn install -DreleaseTesting
|
||||
env:
|
||||
global:
|
||||
secure: ZUzhWfpXJw/oAeDlUkDFkEJMT0T7kCN3d7ah8urkL2B0KFfKOqQagkbXkgvDa1SYud8VdcnoGa69LfkEr5IrdqW7R4bEYZAiN5swm4Z0iO8t53szVspm2f+O9jQ44O/sfOfpfLxWUUuhdc7Vbrszp+tSszxdPmssWL+f5a/mfWs=
|
||||
|
||||
- secure: ZUzhWfpXJw/oAeDlUkDFkEJMT0T7kCN3d7ah8urkL2B0KFfKOqQagkbXkgvDa1SYud8VdcnoGa69LfkEr5IrdqW7R4bEYZAiN5swm4Z0iO8t53szVspm2f+O9jQ44O/sfOfpfLxWUUuhdc7Vbrszp+tSszxdPmssWL+f5a/mfWs=
|
||||
- secure: pmFymoI7qH0Kna3NkcHrqLiTVWKmrhwqA4Z9U6XLhWDQxcs5g94wCCKpGB6Lkz9mkvRxBRFpZZelnXJa9W9mnuVOMIa5tQfS5gBuaNXOe7AXXdc+Y2975OR9sSfvf16FxLFvNJILmZq+bpMLs+EXaQvjYQHW2O6OWZdLhAPVG6A=
|
||||
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)
|
||||
|
||||
- wget -O ~/codacy-coverage-reporter-assembly.jar https://oss.sonatype.org/service/local/repositories/releases/content/com/codacy/codacy-coverage-reporter/1.0.13/codacy-coverage-reporter-1.0.13-assembly.jar
|
||||
after_success:
|
||||
- java -cp ~/codacy-coverage-reporter-assembly-latest.jar com.codacy.CodacyCoverageReporter -l Java -r build-reporting/target/site/jacoco-aggregate/jacoco.xml
|
||||
- java -cp ~/codacy-coverage-reporter-assembly.jar com.codacy.CodacyCoverageReporter
|
||||
-l Java -r build-reporting/target/coverage-reports/jacoco.xml
|
||||
matrix:
|
||||
include:
|
||||
- env: CRON_ONLY=1
|
||||
addons:
|
||||
coverity_scan:
|
||||
project:
|
||||
name: OWASP dependency-check
|
||||
version: 1.0
|
||||
description: A software composition analsis tools that detects publicly
|
||||
disclosed vulnerabilities in application dependencies.
|
||||
build_command: mvn -DskipTests=true package
|
||||
branch_pattern: master
|
||||
|
||||
@@ -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)
|
||||
```
|
||||
|
||||
@@ -20,10 +20,11 @@ Copyright (c) 2017 - Jeremy Long. All Rights Reserved.
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.4.6-SNAPSHOT</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<name>Dependency-Check Build-Reporting</name>
|
||||
<artifactId>build-reporting</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<!-- begin copy from http://minds.coremedia.com/2012/09/11/problem-solved-deploy-multi-module-maven-project-site-as-github-pages/ -->
|
||||
<distributionManagement>
|
||||
<site>
|
||||
@@ -62,6 +63,13 @@ Copyright (c) 2017 - Jeremy Long. All Rights Reserved.
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
@@ -72,6 +80,13 @@ Copyright (c) 2017 - Jeremy Long. All Rights Reserved.
|
||||
<goals>
|
||||
<goal>report-aggregate</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>target/coverage-reports/</outputDirectory>
|
||||
<dataFileIncludes>
|
||||
<dataFileInclude>target/coverage-reports/jacoco-ut.exec</dataFileInclude>
|
||||
<dataFileInclude>target/coverage-reports/jacoco-it.exec</dataFileInclude>
|
||||
</dataFileIncludes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
@@ -20,7 +20,7 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.4.6-SNAPSHOT</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dependency-check-ant</artifactId>
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.4.6-SNAPSHOT</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dependency-check-cli</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());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
@@ -20,7 +20,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.4.6-SNAPSHOT</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dependency-check-core</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 {
|
||||
|
||||
final 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,12 +18,9 @@
|
||||
package org.owasp.dependencycheck.agent;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
|
||||
import org.owasp.dependencycheck.dependency.Dependency;
|
||||
import org.owasp.dependencycheck.dependency.Identifier;
|
||||
import org.owasp.dependencycheck.dependency.Vulnerability;
|
||||
@@ -840,21 +837,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -36,6 +37,7 @@ import java.util.Properties;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import javax.annotation.concurrent.ThreadSafe;
|
||||
import org.apache.commons.collections.map.ReferenceMap;
|
||||
import org.owasp.dependencycheck.data.cwe.CweDB;
|
||||
import org.owasp.dependencycheck.dependency.Reference;
|
||||
import org.owasp.dependencycheck.dependency.Vulnerability;
|
||||
@@ -48,6 +50,8 @@ import org.owasp.dependencycheck.utils.Settings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.apache.commons.collections.map.AbstractReferenceMap.HARD;
|
||||
import static org.apache.commons.collections.map.AbstractReferenceMap.SOFT;
|
||||
import static org.owasp.dependencycheck.data.nvdcve.CveDB.PreparedStatementCveDb.*;
|
||||
|
||||
/**
|
||||
@@ -91,6 +95,12 @@ public final class CveDB implements AutoCloseable {
|
||||
*/
|
||||
private final EnumMap<PreparedStatementCveDb, PreparedStatement> preparedStatements = new EnumMap<>(PreparedStatementCveDb.class);
|
||||
|
||||
/**
|
||||
* Cache for CVE lookups; used to speed up the vulnerability search process.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private final Map<String, List<Vulnerability>> vulnerabilitiesForCpeCache = Collections.synchronizedMap(new ReferenceMap(HARD, SOFT));
|
||||
|
||||
/**
|
||||
* The enum value names must match the keys of the statements in the
|
||||
* statement bundles "dbStatements*.properties".
|
||||
@@ -269,6 +279,7 @@ public final class CveDB implements AutoCloseable {
|
||||
instance.usageCount -= 1;
|
||||
if (instance.usageCount <= 0 && instance.isOpen()) {
|
||||
instance.usageCount = 0;
|
||||
clearCache();
|
||||
instance.closeStatements();
|
||||
try {
|
||||
instance.connection.close();
|
||||
@@ -474,6 +485,7 @@ public final class CveDB implements AutoCloseable {
|
||||
* @param value the property value
|
||||
*/
|
||||
public synchronized void saveProperty(String key, String value) {
|
||||
clearCache();
|
||||
try {
|
||||
try {
|
||||
final PreparedStatement mergeProperty = getPreparedStatement(MERGE_PROPERTY);
|
||||
@@ -498,6 +510,18 @@ public final class CveDB implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears cache. Should be called whenever something is modified. While this
|
||||
* is not the optimal cache eviction strategy, this is good enough for
|
||||
* typical usage (update DB and then only read) and it is easier to maintain
|
||||
* the code.
|
||||
*
|
||||
* It should be also called when DB is closed.
|
||||
*/
|
||||
private void clearCache() {
|
||||
vulnerabilitiesForCpeCache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the vulnerabilities associated with the specified CPE.
|
||||
*
|
||||
@@ -506,6 +530,13 @@ public final class CveDB implements AutoCloseable {
|
||||
* @throws DatabaseException thrown if there is an exception retrieving data
|
||||
*/
|
||||
public synchronized List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException {
|
||||
final List<Vulnerability> cachedVulnerabilities = vulnerabilitiesForCpeCache.get(cpeStr);
|
||||
if (cachedVulnerabilities != null) {
|
||||
LOGGER.debug("Cache hit for {}", cpeStr);
|
||||
return cachedVulnerabilities;
|
||||
} else {
|
||||
LOGGER.debug("Cache miss for {}", cpeStr);
|
||||
}
|
||||
final VulnerableSoftware cpe = new VulnerableSoftware();
|
||||
try {
|
||||
cpe.parseName(cpeStr);
|
||||
@@ -554,6 +585,7 @@ public final class CveDB implements AutoCloseable {
|
||||
} finally {
|
||||
DBUtils.closeResultSet(rs);
|
||||
}
|
||||
vulnerabilitiesForCpeCache.put(cpeStr, vulnerabilities);
|
||||
return vulnerabilities;
|
||||
}
|
||||
|
||||
@@ -633,6 +665,7 @@ public final class CveDB implements AutoCloseable {
|
||||
* @throws DatabaseException is thrown if the database
|
||||
*/
|
||||
public synchronized void updateVulnerability(Vulnerability vuln) throws DatabaseException {
|
||||
clearCache();
|
||||
try {
|
||||
int vulnerabilityId = 0;
|
||||
final PreparedStatement selectVulnerabilityId = getPreparedStatement(SELECT_VULNERABILITY_ID);
|
||||
@@ -799,6 +832,7 @@ public final class CveDB implements AutoCloseable {
|
||||
* ensure orphan entries are removed.
|
||||
*/
|
||||
public synchronized void cleanupDatabase() {
|
||||
clearCache();
|
||||
try {
|
||||
final PreparedStatement ps = getPreparedStatement(CLEANUP_ORPHANS);
|
||||
if (ps != null) {
|
||||
@@ -934,6 +968,7 @@ public final class CveDB implements AutoCloseable {
|
||||
* Deletes unused dictionary entries from the database.
|
||||
*/
|
||||
public synchronized void deleteUnusedCpe() {
|
||||
clearCache();
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = connection.prepareStatement(statementBundle.getString("DELETE_UNUSED_DICT_CPE"));
|
||||
@@ -956,6 +991,7 @@ public final class CveDB implements AutoCloseable {
|
||||
* @param product the CPE product
|
||||
*/
|
||||
public synchronized void addCpe(String cpe, String vendor, String product) {
|
||||
clearCache();
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = connection.prepareStatement(statementBundle.getString("ADD_DICT_CPE"));
|
||||
|
||||
@@ -124,7 +124,7 @@ public class EscapeTool {
|
||||
return "";
|
||||
}
|
||||
boolean addComma = false;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (Identifier id : ids) {
|
||||
if (!"cpe".equals(id.getType())) {
|
||||
if (addComma) {
|
||||
@@ -150,7 +150,7 @@ public class EscapeTool {
|
||||
return "";
|
||||
}
|
||||
boolean addComma = false;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (Identifier id : ids) {
|
||||
if ("cpe".equals(id.getType())) {
|
||||
if (addComma) {
|
||||
|
||||
@@ -107,29 +107,8 @@ 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();
|
||||
|
||||
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 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"));
|
||||
context = createContext(applicationName, dependencies, analyzers, properties);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,9 +127,15 @@ public class ReportGenerator {
|
||||
List<Dependency> dependencies, List<Analyzer> analyzers, DatabaseProperties properties) {
|
||||
|
||||
this(applicationName, dependencies, analyzers, properties);
|
||||
context.put("applicationVersion", version);
|
||||
context.put("artifactID", artifactID);
|
||||
context.put("groupID", groupID);
|
||||
if (version != null) {
|
||||
context.put("applicationVersion", version);
|
||||
}
|
||||
if (artifactID != null) {
|
||||
context.put("artifactID", artifactID);
|
||||
}
|
||||
if (groupID != null) {
|
||||
context.put("groupID", groupID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,67 +151,235 @@ 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);
|
||||
|
||||
final 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);
|
||||
}
|
||||
if (format == Format.JSON || format == Format.ALL) {
|
||||
generateReport("JsonReport", outputStream);
|
||||
}
|
||||
if (format == Format.CSV || format == Format.ALL) {
|
||||
generateReport("CsvReport", 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
|
||||
* @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, Format format) throws ReportException {
|
||||
if (format == Format.XML || format == Format.ALL) {
|
||||
generateReport("XmlReport", outputDir + File.separator + "dependency-check-report.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 (format == Format.JSON || format == Format.ALL) {
|
||||
generateReport("JsonReport", outputDir + File.separator + "dependency-check-report.json");
|
||||
pretifyJson(outputDir + File.separator + "dependency-check-report.json");
|
||||
|
||||
if (reportFormat != null) {
|
||||
write(outputLocation, reportFormat);
|
||||
} else {
|
||||
final 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);
|
||||
}
|
||||
if (format == Format.CSV || format == Format.ALL) {
|
||||
generateReport("CsvReport", outputDir + File.separator + "dependency-check-report.csv");
|
||||
}
|
||||
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");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
} 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
|
||||
* 'XmlReport' or 'HtmlReport', or the template name can be the path to a
|
||||
* template file.
|
||||
*
|
||||
* @param templateName the name of the template to load
|
||||
* @param outputStream the OutputStream to write the report to
|
||||
* @throws ReportException is thrown when an exception occurs
|
||||
*/
|
||||
protected void processTemplate(String templateName, OutputStream outputStream) throws ReportException {
|
||||
InputStream input = null;
|
||||
String logTag = null;
|
||||
final File f = new File(templateName);
|
||||
try {
|
||||
if (f.isFile()) {
|
||||
try {
|
||||
logTag = templateName;
|
||||
input = new FileInputStream(f);
|
||||
} catch (FileNotFoundException ex) {
|
||||
throw new ReportException("Unable to locate template file: " + templateName, ex);
|
||||
}
|
||||
} else {
|
||||
logTag = "templates/" + templateName + ".vsl";
|
||||
input = this.getClass().getClassLoader().getResourceAsStream(logTag);
|
||||
}
|
||||
if (input == null) {
|
||||
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, logTag, reader)) {
|
||||
throw new ReportException("Failed to convert the template into html.");
|
||||
}
|
||||
writer.flush();
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
throw new ReportException("Unable to generate the report using UTF-8", ex);
|
||||
} catch (IOException ex) {
|
||||
throw new ReportException("Unable to write the report", ex);
|
||||
}
|
||||
} finally {
|
||||
if (input != null) {
|
||||
try {
|
||||
input.close();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.trace("Error closing input", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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 file the file or directory directory
|
||||
* @throws ReportException thrown if the parent directory does not exist and
|
||||
* cannot be created
|
||||
*/
|
||||
private void ensureParentDirectoryExists(File file) throws ReportException {
|
||||
if (!file.getParentFile().exists()) {
|
||||
final boolean created = file.getParentFile().mkdirs();
|
||||
if (!created) {
|
||||
final String msg = String.format("Unable to create directory '%s'.", file.getParentFile().getAbsolutePath());
|
||||
throw new ReportException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Reformats the given JSON file.
|
||||
*
|
||||
@@ -311,139 +464,4 @@ public class ReportGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* @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|JSON|ALL)$")) {
|
||||
if ("XML".equalsIgnoreCase(format)) {
|
||||
if (pathToCheck.endsWith(".xml")) {
|
||||
generateReport("XmlReport", outputDir);
|
||||
} else {
|
||||
generateReports(outputDir, Format.XML);
|
||||
}
|
||||
}
|
||||
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 ("JSON".equalsIgnoreCase(format)) {
|
||||
if (pathToCheck.endsWith(".json")) {
|
||||
generateReport("JsonReport", outputDir);
|
||||
pretifyJson(outputDir);
|
||||
} else {
|
||||
generateReports(outputDir, Format.JSON);
|
||||
}
|
||||
}
|
||||
if ("CSV".equalsIgnoreCase(format)) {
|
||||
if (pathToCheck.endsWith(".csv")) {
|
||||
generateReport("CsvReport", outputDir);
|
||||
} else {
|
||||
generateReports(outputDir, Format.JSON);
|
||||
}
|
||||
}
|
||||
if ("ALL".equalsIgnoreCase(format)) {
|
||||
generateReports(outputDir, Format.ALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 templateName the name of the template to load
|
||||
* @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 {
|
||||
InputStream input = null;
|
||||
String templatePath = null;
|
||||
final File f = new File(templateName);
|
||||
try {
|
||||
if (f.exists() && f.isFile()) {
|
||||
try {
|
||||
templatePath = 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);
|
||||
}
|
||||
if (input == null) {
|
||||
throw new ReportException("Template file doesn't exist: " + templatePath);
|
||||
}
|
||||
|
||||
try (InputStreamReader reader = new InputStreamReader(input, "UTF-8");
|
||||
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8")) {
|
||||
if (!velocityEngine.evaluate(context, writer, templatePath, reader)) {
|
||||
throw new ReportException("Failed to convert the template into html.");
|
||||
}
|
||||
writer.flush();
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
throw new ReportException("Unable to generate the report using UTF-8", ex);
|
||||
} catch (IOException ex) {
|
||||
throw new ReportException("Unable to write the report", ex);
|
||||
}
|
||||
} finally {
|
||||
if (input != null) {
|
||||
try {
|
||||
input.close();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.trace("Error closing input", 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
|
||||
* 'XmlReport' or 'HtmlReport', or the template name can be the path to a
|
||||
* template file.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
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();
|
||||
if (!created) {
|
||||
throw new ReportException("Unable to create directory '" + outFile.getParentFile().getAbsolutePath() + "'.");
|
||||
}
|
||||
}
|
||||
try (OutputStream outputSteam = new FileOutputStream(outFile)) {
|
||||
generateReport(templateName, outputSteam);
|
||||
} catch (IOException ex) {
|
||||
throw new ReportException("Unable to write to file: " + outFile, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
package org.owasp.dependencycheck.xml;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This is a utility class to convert named XML Entities (such as ø) into
|
||||
* its HTML encoded Unicode code point (i.e. &#248;). This is a slightly
|
||||
* modified (class/method rename) from an SO answer:
|
||||
* https://stackoverflow.com/questions/7286428/help-the-java-sax-parser-to-understand-bad-xml
|
||||
*
|
||||
* @author https://stackoverflow.com/users/823393/oldcurmudgeon
|
||||
*/
|
||||
public class XmlEntity {
|
||||
/**
|
||||
* The map of HTML entities.
|
||||
*/
|
||||
private static final Map<String, Integer> SPECIALS;
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc="Initialize SPECIALS">
|
||||
/**
|
||||
* Create a map HTML Named Entities to their numeric equivalent. Derived
|
||||
* from Wikipedia
|
||||
* http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
|
||||
*/
|
||||
static {
|
||||
final Map<String, Integer> map = new HashMap<>();
|
||||
map.put("quot", 34);
|
||||
map.put("amp", 38);
|
||||
map.put("apos", 39);
|
||||
map.put("lt", 60);
|
||||
map.put("gt", 62);
|
||||
map.put("nbsp", 160);
|
||||
map.put("iexcl", 161);
|
||||
map.put("cent", 162);
|
||||
map.put("pound", 163);
|
||||
map.put("curren", 164);
|
||||
map.put("yen", 165);
|
||||
map.put("brvbar", 166);
|
||||
map.put("sect", 167);
|
||||
map.put("uml", 168);
|
||||
map.put("copy", 169);
|
||||
map.put("ordf", 170);
|
||||
map.put("laquo", 171);
|
||||
map.put("not", 172);
|
||||
map.put("shy", 173);
|
||||
map.put("reg", 174);
|
||||
map.put("macr", 175);
|
||||
map.put("deg", 176);
|
||||
map.put("plusmn", 177);
|
||||
map.put("sup2", 178);
|
||||
map.put("sup3", 179);
|
||||
map.put("acute", 180);
|
||||
map.put("micro", 181);
|
||||
map.put("para", 182);
|
||||
map.put("middot", 183);
|
||||
map.put("cedil", 184);
|
||||
map.put("sup1", 185);
|
||||
map.put("ordm", 186);
|
||||
map.put("raquo", 187);
|
||||
map.put("frac14", 188);
|
||||
map.put("frac12", 189);
|
||||
map.put("frac34", 190);
|
||||
map.put("iquest", 191);
|
||||
map.put("Agrave", 192);
|
||||
map.put("Aacute", 193);
|
||||
map.put("Acirc", 194);
|
||||
map.put("Atilde", 195);
|
||||
map.put("Auml", 196);
|
||||
map.put("Aring", 197);
|
||||
map.put("AElig", 198);
|
||||
map.put("Ccedil", 199);
|
||||
map.put("Egrave", 200);
|
||||
map.put("Eacute", 201);
|
||||
map.put("Ecirc", 202);
|
||||
map.put("Euml", 203);
|
||||
map.put("Igrave", 204);
|
||||
map.put("Iacute", 205);
|
||||
map.put("Icirc", 206);
|
||||
map.put("Iuml", 207);
|
||||
map.put("ETH", 208);
|
||||
map.put("Ntilde", 209);
|
||||
map.put("Ograve", 210);
|
||||
map.put("Oacute", 211);
|
||||
map.put("Ocirc", 212);
|
||||
map.put("Otilde", 213);
|
||||
map.put("Ouml", 214);
|
||||
map.put("times", 215);
|
||||
map.put("Oslash", 216);
|
||||
map.put("Ugrave", 217);
|
||||
map.put("Uacute", 218);
|
||||
map.put("Ucirc", 219);
|
||||
map.put("Uuml", 220);
|
||||
map.put("Yacute", 221);
|
||||
map.put("THORN", 222);
|
||||
map.put("szlig", 223);
|
||||
map.put("agrave", 224);
|
||||
map.put("aacute", 225);
|
||||
map.put("acirc", 226);
|
||||
map.put("atilde", 227);
|
||||
map.put("auml", 228);
|
||||
map.put("aring", 229);
|
||||
map.put("aelig", 230);
|
||||
map.put("ccedil", 231);
|
||||
map.put("egrave", 232);
|
||||
map.put("eacute", 233);
|
||||
map.put("ecirc", 234);
|
||||
map.put("euml", 235);
|
||||
map.put("igrave", 236);
|
||||
map.put("iacute", 237);
|
||||
map.put("icirc", 238);
|
||||
map.put("iuml", 239);
|
||||
map.put("eth", 240);
|
||||
map.put("ntilde", 241);
|
||||
map.put("ograve", 242);
|
||||
map.put("oacute", 243);
|
||||
map.put("ocirc", 244);
|
||||
map.put("otilde", 245);
|
||||
map.put("ouml", 246);
|
||||
map.put("divide", 247);
|
||||
map.put("oslash", 248);
|
||||
map.put("ugrave", 249);
|
||||
map.put("uacute", 250);
|
||||
map.put("ucirc", 251);
|
||||
map.put("uuml", 252);
|
||||
map.put("yacute", 253);
|
||||
map.put("thorn", 254);
|
||||
map.put("yuml", 255);
|
||||
map.put("OElig", 338);
|
||||
map.put("oelig", 339);
|
||||
map.put("Scaron", 352);
|
||||
map.put("scaron", 353);
|
||||
map.put("Yuml", 376);
|
||||
map.put("fnof", 402);
|
||||
map.put("circ", 710);
|
||||
map.put("tilde", 732);
|
||||
map.put("Alpha", 913);
|
||||
map.put("Beta", 914);
|
||||
map.put("Gamma", 915);
|
||||
map.put("Delta", 916);
|
||||
map.put("Epsilon", 917);
|
||||
map.put("Zeta", 918);
|
||||
map.put("Eta", 919);
|
||||
map.put("Theta", 920);
|
||||
map.put("Iota", 921);
|
||||
map.put("Kappa", 922);
|
||||
map.put("Lambda", 923);
|
||||
map.put("Mu", 924);
|
||||
map.put("Nu", 925);
|
||||
map.put("Xi", 926);
|
||||
map.put("Omicron", 927);
|
||||
map.put("Pi", 928);
|
||||
map.put("Rho", 929);
|
||||
map.put("Sigma", 931);
|
||||
map.put("Tau", 932);
|
||||
map.put("Upsilon", 933);
|
||||
map.put("Phi", 934);
|
||||
map.put("Chi", 935);
|
||||
map.put("Psi", 936);
|
||||
map.put("Omega", 937);
|
||||
map.put("alpha", 945);
|
||||
map.put("beta", 946);
|
||||
map.put("gamma", 947);
|
||||
map.put("delta", 948);
|
||||
map.put("epsilon", 949);
|
||||
map.put("zeta", 950);
|
||||
map.put("eta", 951);
|
||||
map.put("theta", 952);
|
||||
map.put("iota", 953);
|
||||
map.put("kappa", 954);
|
||||
map.put("lambda", 955);
|
||||
map.put("mu", 956);
|
||||
map.put("nu", 957);
|
||||
map.put("xi", 958);
|
||||
map.put("omicron", 959);
|
||||
map.put("pi", 960);
|
||||
map.put("rho", 961);
|
||||
map.put("sigmaf", 962);
|
||||
map.put("sigma", 963);
|
||||
map.put("tau", 964);
|
||||
map.put("upsilon", 965);
|
||||
map.put("phi", 966);
|
||||
map.put("chi", 967);
|
||||
map.put("psi", 968);
|
||||
map.put("omega", 969);
|
||||
map.put("thetasym", 977);
|
||||
map.put("upsih", 978);
|
||||
map.put("piv", 982);
|
||||
map.put("ensp", 8194);
|
||||
map.put("emsp", 8195);
|
||||
map.put("thinsp", 8201);
|
||||
map.put("zwnj", 8204);
|
||||
map.put("zwj", 8205);
|
||||
map.put("lrm", 8206);
|
||||
map.put("rlm", 8207);
|
||||
map.put("ndash", 8211);
|
||||
map.put("mdash", 8212);
|
||||
map.put("lsquo", 8216);
|
||||
map.put("rsquo", 8217);
|
||||
map.put("sbquo", 8218);
|
||||
map.put("ldquo", 8220);
|
||||
map.put("rdquo", 8221);
|
||||
map.put("bdquo", 8222);
|
||||
map.put("dagger", 8224);
|
||||
map.put("Dagger", 8225);
|
||||
map.put("bull", 8226);
|
||||
map.put("hellip", 8230);
|
||||
map.put("permil", 8240);
|
||||
map.put("prime", 8242);
|
||||
map.put("Prime", 8243);
|
||||
map.put("lsaquo", 8249);
|
||||
map.put("rsaquo", 8250);
|
||||
map.put("oline", 8254);
|
||||
map.put("frasl", 8260);
|
||||
map.put("euro", 8364);
|
||||
map.put("image", 8465);
|
||||
map.put("weierp", 8472);
|
||||
map.put("real", 8476);
|
||||
map.put("trade", 8482);
|
||||
map.put("alefsym", 8501);
|
||||
map.put("larr", 8592);
|
||||
map.put("uarr", 8593);
|
||||
map.put("rarr", 8594);
|
||||
map.put("darr", 8595);
|
||||
map.put("harr", 8596);
|
||||
map.put("crarr", 8629);
|
||||
map.put("lArr", 8656);
|
||||
map.put("uArr", 8657);
|
||||
map.put("rArr", 8658);
|
||||
map.put("dArr", 8659);
|
||||
map.put("hArr", 8660);
|
||||
map.put("forall", 8704);
|
||||
map.put("part", 8706);
|
||||
map.put("exist", 8707);
|
||||
map.put("empty", 8709);
|
||||
map.put("nabla", 8711);
|
||||
map.put("isin", 8712);
|
||||
map.put("notin", 8713);
|
||||
map.put("ni", 8715);
|
||||
map.put("prod", 8719);
|
||||
map.put("sum", 8721);
|
||||
map.put("minus", 8722);
|
||||
map.put("lowast", 8727);
|
||||
map.put("radic", 8730);
|
||||
map.put("prop", 8733);
|
||||
map.put("infin", 8734);
|
||||
map.put("ang", 8736);
|
||||
map.put("and", 8743);
|
||||
map.put("or", 8744);
|
||||
map.put("cap", 8745);
|
||||
map.put("cup", 8746);
|
||||
map.put("int", 8747);
|
||||
map.put("there4", 8756);
|
||||
map.put("sim", 8764);
|
||||
map.put("cong", 8773);
|
||||
map.put("asymp", 8776);
|
||||
map.put("ne", 8800);
|
||||
map.put("equiv", 8801);
|
||||
map.put("le", 8804);
|
||||
map.put("ge", 8805);
|
||||
map.put("sub", 8834);
|
||||
map.put("sup", 8835);
|
||||
map.put("nsub", 8836);
|
||||
map.put("sube", 8838);
|
||||
map.put("supe", 8839);
|
||||
map.put("oplus", 8853);
|
||||
map.put("otimes", 8855);
|
||||
map.put("perp", 8869);
|
||||
map.put("sdot", 8901);
|
||||
map.put("lceil", 8968);
|
||||
map.put("rceil", 8969);
|
||||
map.put("lfloor", 8970);
|
||||
map.put("rfloor", 8971);
|
||||
map.put("lang", 10216);
|
||||
map.put("rang", 10217);
|
||||
map.put("loz", 9674);
|
||||
map.put("spades", 9824);
|
||||
map.put("clubs", 9827);
|
||||
map.put("hearts", 9829);
|
||||
map.put("diams", 9830);
|
||||
SPECIALS = Collections.unmodifiableMap(map);
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
/**
|
||||
* Private constructor for a utility class.
|
||||
*/
|
||||
private XmlEntity() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a named XML entity into its HTML encoded Unicode code point.
|
||||
*
|
||||
* @param s the named entity (note, this should not include the leading '&'
|
||||
* or trailing ';'
|
||||
* @return the HTML encoded Unicode code point representation of the named
|
||||
* entity
|
||||
*/
|
||||
public static String fromNamedReference(CharSequence s) {
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
final Integer code = SPECIALS.get(s.toString());
|
||||
if (code != null) {
|
||||
return "&#" + code + ";";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
package org.owasp.dependencycheck.xml;
|
||||
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Cleans up often very bad XML. Primarily, this will convert named HTM entities
|
||||
* into their HTM encoded Unicode code point representation.
|
||||
*
|
||||
* <ol>
|
||||
* <li>Strips leading white space</li>
|
||||
* <li>Recodes &pound; etc to &#...;</li>
|
||||
* <li>Recodes lone & as &amp;</li>
|
||||
* </ol>
|
||||
* <p>
|
||||
* This is a slightly modified (class/method rename) from an SO answer:
|
||||
* https://stackoverflow.com/questions/7286428/help-the-java-sax-parser-to-understand-bad-xml</p>
|
||||
*
|
||||
* @author https://stackoverflow.com/users/823393/oldcurmudgeon
|
||||
*/
|
||||
public class XmlInputStream extends FilterInputStream {
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*/
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(XmlInputStream.class);
|
||||
/**
|
||||
* The minimum length of characters to read.
|
||||
*/
|
||||
private static final int MIN_LENGTH = 2;
|
||||
/**
|
||||
* Holder for everything we've read.
|
||||
*/
|
||||
private StringBuilder red = new StringBuilder();
|
||||
/**
|
||||
* Data that needs to be pushed back.
|
||||
*/
|
||||
private StringBuilder pushBack = new StringBuilder();
|
||||
/**
|
||||
* How much we've given them.
|
||||
*/
|
||||
private int given = 0;
|
||||
/**
|
||||
* How much we've read.
|
||||
*/
|
||||
private int pulled = 0;
|
||||
|
||||
/**
|
||||
* Constructs a new XML Input Stream.
|
||||
*
|
||||
* @param in the base input stream
|
||||
*/
|
||||
public XmlInputStream(InputStream in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* NB: This is a Troll length (i.e. it goes 1, 2, many) so 2 actually means
|
||||
* "at least 2"
|
||||
*
|
||||
* @return the length
|
||||
*/
|
||||
public int length() {
|
||||
try {
|
||||
final StringBuilder s = read(MIN_LENGTH);
|
||||
pushBack.append(s);
|
||||
return s.length();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.warn("Oops ", ex);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read n characters.
|
||||
*
|
||||
* @param n the number of characters to read
|
||||
* @return the characters read
|
||||
* @throws IOException thrown when an error occurs
|
||||
*/
|
||||
private StringBuilder read(int n) throws IOException {
|
||||
// Input stream finished?
|
||||
boolean eof = false;
|
||||
// Read that many.
|
||||
final StringBuilder s = new StringBuilder(n);
|
||||
while (s.length() < n && !eof) {
|
||||
// Always get from the pushBack buffer.
|
||||
if (pushBack.length() == 0) {
|
||||
// Read something from the stream into pushBack.
|
||||
eof = readIntoPushBack();
|
||||
}
|
||||
|
||||
// Pushback only contains deliverable codes.
|
||||
if (pushBack.length() > 0) {
|
||||
// Grab one character
|
||||
s.append(pushBack.charAt(0));
|
||||
// Remove it from pushBack
|
||||
pushBack.deleteCharAt(0);
|
||||
}
|
||||
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Might not actually push back anything but usually will.
|
||||
*
|
||||
* @return true if at end-of-file
|
||||
* @throws IOException thrown if there is an IO exception in the underlying
|
||||
* steam
|
||||
*/
|
||||
private boolean readIntoPushBack() throws IOException {
|
||||
// File finished?
|
||||
boolean eof = false;
|
||||
// Next char.
|
||||
final int ch = in.read();
|
||||
if (ch >= 0) {
|
||||
// Discard whitespace at start?
|
||||
if (!(pulled == 0 && isWhiteSpace(ch))) {
|
||||
// Good code.
|
||||
pulled += 1;
|
||||
// Parse out the &stuff;
|
||||
if (ch == '&') {
|
||||
// Process the &
|
||||
readAmpersand();
|
||||
} else {
|
||||
// Not an '&', just append.
|
||||
pushBack.append((char) ch);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Hit end of file.
|
||||
eof = true;
|
||||
}
|
||||
return eof;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deal with an ampersand in the stream.
|
||||
*
|
||||
* @throws IOException thrown if an unknown entity is encountered
|
||||
*/
|
||||
private void readAmpersand() throws IOException {
|
||||
// Read the whole word, up to and including the ;
|
||||
final StringBuilder reference = new StringBuilder();
|
||||
int ch;
|
||||
// Should end in a ';'
|
||||
for (ch = in.read(); isAlphaNumeric(ch); ch = in.read()) {
|
||||
reference.append((char) ch);
|
||||
}
|
||||
// Did we tidily finish?
|
||||
if (ch == ';') {
|
||||
// Yes! Translate it into a &#nnn; code.
|
||||
final String code = XmlEntity.fromNamedReference(reference);
|
||||
if (code != null) {
|
||||
// Keep it.
|
||||
pushBack.append(code);
|
||||
} else {
|
||||
throw new IOException("Invalid/Unknown reference '&" + reference + ";'");
|
||||
}
|
||||
} else {
|
||||
// Did not terminate properly!
|
||||
// Perhaps an & on its own or a malformed reference.
|
||||
// Either way, escape the &
|
||||
pushBack.append("&").append(reference).append((char) ch);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep track of what we've given them.
|
||||
*
|
||||
* @param s the sequence of characters given
|
||||
* @param wanted the number of characters wanted
|
||||
* @param got the number of characters given
|
||||
*/
|
||||
private void given(CharSequence s, int wanted, int got) {
|
||||
red.append(s);
|
||||
given += got;
|
||||
LOGGER.trace("Given: [" + wanted + "," + got + "]-" + s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next byte.
|
||||
*
|
||||
* @return the byte read
|
||||
* @throws IOException thrown when there is an problem reading
|
||||
*/
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
final StringBuilder s = read(1);
|
||||
given(s, 1, 1);
|
||||
return s.length() > 0 ? s.charAt(0) : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next length of bytes from the stream into the given byte array
|
||||
* at the given offset.
|
||||
*
|
||||
* @param data the buffer to store the data read
|
||||
* @param offset the offset in the buffer to start writing
|
||||
* @param length the length of data to read
|
||||
* @return the number of bytes read
|
||||
* @throws IOException thrown when there is an issue with the underlying
|
||||
* stream
|
||||
*/
|
||||
@Override
|
||||
public int read(byte[] data, int offset, int length) throws IOException {
|
||||
final StringBuilder s = read(length);
|
||||
int n = 0;
|
||||
for (int i = 0; i < Math.min(length, s.length()); i++) {
|
||||
data[offset + i] = (byte) s.charAt(i);
|
||||
n += 1;
|
||||
}
|
||||
given(s, length, n);
|
||||
return n > 0 ? n : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* To string implementation.
|
||||
*
|
||||
* @return a string representation of the data given and read from the
|
||||
* stream.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
final String s = red.toString();
|
||||
final StringBuilder h = new StringBuilder();
|
||||
// Hex dump the small ones.
|
||||
if (s.length() < 8) {
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
h.append(" ").append(Integer.toHexString(s.charAt(i)));
|
||||
}
|
||||
}
|
||||
return "[" + given + "]-\"" + s + "\"" + (h.length() > 0 ? " (" + h.toString() + ")" : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the character is whitespace.
|
||||
*
|
||||
* @param ch the character to check
|
||||
* @return true if the character is whitespace; otherwise false
|
||||
*/
|
||||
private boolean isWhiteSpace(int ch) {
|
||||
switch (ch) {
|
||||
case ' ':
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\t':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given character is alpha-numeric.
|
||||
*
|
||||
* @param ch the character to check
|
||||
* @return true if the character is alpha-numeric; otherwise false.
|
||||
*/
|
||||
private boolean isAlphaNumeric(int ch) {
|
||||
return ('a' <= ch && ch <= 'z')
|
||||
|| ('A' <= ch && ch <= 'Z')
|
||||
|| ('0' <= ch && ch <= '9');
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import javax.xml.parsers.SAXParser;
|
||||
import org.apache.commons.io.ByteOrderMark;
|
||||
import org.apache.commons.io.input.BOMInputStream;
|
||||
import org.owasp.dependencycheck.utils.XmlUtils;
|
||||
import org.owasp.dependencycheck.xml.XmlInputStream;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -80,7 +81,8 @@ public class PomParser {
|
||||
final SAXParser saxParser = XmlUtils.buildSecureSaxParser();
|
||||
final XMLReader xmlReader = saxParser.getXMLReader();
|
||||
xmlReader.setContentHandler(handler);
|
||||
final BOMInputStream bomStream = new BOMInputStream(inputStream);
|
||||
|
||||
final BOMInputStream bomStream = new BOMInputStream(new XmlInputStream(inputStream));
|
||||
final ByteOrderMark bom = bomStream.getBOM();
|
||||
final String defaultEncoding = "UTF-8";
|
||||
final String charsetName = bom == null ? defaultEncoding : bom.getCharsetName();
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.1.xsd">
|
||||
<suppress base="true">
|
||||
<notes><![CDATA[
|
||||
<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>
|
||||
<filePath regex="true">.*Microsoft\.VisualStudio\.QualityTools\.UnitTestFramework*\.dll</filePath>
|
||||
<cve>CVE-2014-3802</cve>
|
||||
</suppress>
|
||||
<suppress base="true">
|
||||
<notes><![CDATA[
|
||||
<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>
|
||||
<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[
|
||||
@@ -582,24 +582,24 @@
|
||||
]]></notes>
|
||||
<gav regex="true">^com\.splunk:splunk:.*$</gav>
|
||||
<cpe>cpe:/a:splunk:splunk</cpe>
|
||||
</suppress>
|
||||
<suppress base="true">
|
||||
</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">
|
||||
</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">
|
||||
</suppress>
|
||||
<suppress base="true">
|
||||
<notes><![CDATA[
|
||||
False positive per issue #700
|
||||
]]></notes>
|
||||
@@ -607,5 +607,20 @@
|
||||
<cpe>cpe:/a:pivotal:spring_framework</cpe>
|
||||
<cpe>cpe:/a:pivotal_software:spring_framework</cpe>
|
||||
<cpe>cpe:/a:context_project:context</cpe>
|
||||
</suppress>
|
||||
</suppress>
|
||||
<suppress base="true">
|
||||
<notes><![CDATA[
|
||||
False Positive per issue #746
|
||||
]]></notes>
|
||||
<gav regex="true">^com\.artofsolving:jodconverter:.*$</gav>
|
||||
<cpe>cpe:/a:openoffice:openoffice.org</cpe>
|
||||
<cpe>cpe:/a:openoffice:openoffice</cpe>
|
||||
</suppress>
|
||||
<suppress base="true">
|
||||
<notes><![CDATA[
|
||||
False Positive per issue #743
|
||||
]]></notes>
|
||||
<gav regex="true">^org\.xerial:sqlite-jdbc:.*$</gav>
|
||||
<cve>CVE-2015-3717</cve>
|
||||
</suppress>
|
||||
</suppressions>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@@ -79,12 +80,7 @@ public class EngineIT extends BaseDBTestCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,15 +25,12 @@ 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;
|
||||
@@ -47,67 +44,6 @@ import static org.junit.Assert.fail;
|
||||
*/
|
||||
public class ReportGeneratorIT 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.
|
||||
@@ -115,7 +51,7 @@ public class ReportGeneratorIT extends BaseDBTestCase {
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testGenerateXMLReport() {
|
||||
public void testGenerateReport() {
|
||||
try {
|
||||
String templateName = "XmlReport";
|
||||
|
||||
@@ -123,7 +59,7 @@ public class ReportGeneratorIT extends BaseDBTestCase {
|
||||
if (!f.exists()) {
|
||||
f.mkdir();
|
||||
}
|
||||
String writeTo = "target/test-reports/Report.xml";
|
||||
File writeTo = new File("target/test-reports/Report.xml");
|
||||
File suppressionFile = BaseTest.getResourceAsFile(this, "incorrectSuppressions.xml");
|
||||
|
||||
Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile.getAbsolutePath());
|
||||
@@ -135,29 +71,20 @@ public class ReportGeneratorIT extends BaseDBTestCase {
|
||||
//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", "org.owasp", "dependency-check-core", "1.4.7",
|
||||
engine.getDependencies(), engine.getAnalyzers(), dbProp);
|
||||
generator.generateReport(templateName, writeTo);
|
||||
cveDB.close();
|
||||
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(new File(writeTo));
|
||||
StreamSource xmlSource = new StreamSource(writeTo);
|
||||
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||
Schema schema = sf.newSchema(xsdSource);
|
||||
Validator validator = schema.newValidator();
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.xml;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
public class XmlEntityTest {
|
||||
|
||||
/**
|
||||
* Test of fromNamedReference method, of class XmlEntity.
|
||||
*/
|
||||
@Test
|
||||
public void testFromNamedReference() {
|
||||
CharSequence s = null;
|
||||
String expResult = null;
|
||||
String result = XmlEntity.fromNamedReference(s);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
s = "somethingWrong";
|
||||
expResult = null;
|
||||
result = XmlEntity.fromNamedReference(s);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
s = "amp";
|
||||
expResult = "&";
|
||||
result = XmlEntity.fromNamedReference(s);
|
||||
assertEquals(expResult, result);
|
||||
|
||||
s = "acute";
|
||||
expResult = "´";
|
||||
result = XmlEntity.fromNamedReference(s);
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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.xml;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jerem
|
||||
*/
|
||||
public class XmlInputStreamTest {
|
||||
|
||||
/**
|
||||
* Test of length method, of class XmlInputStream.
|
||||
*/
|
||||
@Test
|
||||
public void testLength() {
|
||||
String data = "";
|
||||
InputStream stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
|
||||
XmlInputStream instance = new XmlInputStream(stream);
|
||||
int expResult = 0;
|
||||
int result = instance.length();
|
||||
assertEquals(expResult, result);
|
||||
|
||||
data = "Input data";
|
||||
stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
|
||||
instance = new XmlInputStream(stream);
|
||||
result = instance.length();
|
||||
assertTrue(result > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of read method, of class XmlInputStream.
|
||||
*/
|
||||
@Test
|
||||
public void testRead_0args() throws Exception {
|
||||
String data = "";
|
||||
InputStream stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
|
||||
XmlInputStream instance = new XmlInputStream(stream);
|
||||
int expResult = -1;
|
||||
int result = instance.read();
|
||||
assertEquals(expResult, result);
|
||||
|
||||
data = "*";
|
||||
stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
|
||||
instance = new XmlInputStream(stream);
|
||||
expResult = 42;
|
||||
result = instance.read();
|
||||
assertEquals(expResult, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of read method, of class XmlInputStream.
|
||||
*/
|
||||
@Test
|
||||
public void testRead_3args() throws Exception {
|
||||
byte[] data = new byte[10];
|
||||
int offset = 0;
|
||||
int length = 10;
|
||||
byte[] expected = "abcdefghij".getBytes(StandardCharsets.UTF_8);
|
||||
String text = "abcdefghijklmnopqrstuvwxyz";
|
||||
InputStream stream = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
|
||||
XmlInputStream instance = new XmlInputStream(stream);
|
||||
int expResult = 10;
|
||||
int result = instance.read(data, offset, length);
|
||||
assertEquals(expResult, result);
|
||||
assertArrayEquals(expected, data);
|
||||
|
||||
|
||||
data = new byte[5];
|
||||
offset = 0;
|
||||
length = 5;
|
||||
expected = "&".getBytes(StandardCharsets.UTF_8);
|
||||
text = "&";
|
||||
stream = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
|
||||
instance = new XmlInputStream(stream);
|
||||
expResult = 5;
|
||||
result = instance.read(data, offset, length);
|
||||
assertEquals(expResult, result);
|
||||
assertArrayEquals(expected, data);
|
||||
|
||||
data = new byte[10];
|
||||
offset = 0;
|
||||
length = 10;
|
||||
expected = "& test".getBytes(StandardCharsets.UTF_8);
|
||||
text = "& test";
|
||||
stream = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
|
||||
instance = new XmlInputStream(stream);
|
||||
expResult = 10;
|
||||
result = instance.read(data, offset, length);
|
||||
assertEquals(expResult, result);
|
||||
assertArrayEquals(expected, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of toString method, of class XmlInputStream.
|
||||
*/
|
||||
@Test
|
||||
public void testToString() throws IOException {
|
||||
String data = "test";
|
||||
InputStream stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
|
||||
XmlInputStream instance = new XmlInputStream(stream);
|
||||
int r = instance.read();
|
||||
assertEquals('t', r);
|
||||
String expResult = "[1]-\"t\" ( 74)";
|
||||
String result = instance.toString();
|
||||
assertEquals(expResult, result);
|
||||
r = instance.read();
|
||||
assertEquals('e', r);
|
||||
expResult = "[2]-\"te\" ( 74 65)";
|
||||
result = instance.toString();
|
||||
assertEquals(expResult, result);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@ public class PomUtilsTest extends BaseTest {
|
||||
assertEquals(expResult, result.getOrganizationUrl());
|
||||
|
||||
file = BaseTest.getResourceAsFile(this, "jmockit-1.26.pom");
|
||||
expResult = "Main";
|
||||
expResult = "Main ø modified to test issue #710";
|
||||
result = PomUtils.readPom(file);
|
||||
assertEquals(expResult, result.getName());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<groupId>org.jmockit</groupId><artifactId>jmockit</artifactId><version>1.26</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Main</name>
|
||||
<name>Main ø modified to test issue #710</name>
|
||||
<description>
|
||||
JMockit is a Java toolkit for automated developer testing.
|
||||
It contains mocking and faking APIs and a code coverage tool, supporting both JUnit and TestNG.
|
||||
|
||||
@@ -20,7 +20,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.4.6-SNAPSHOT</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>dependency-check-maven</artifactId>
|
||||
<packaging>maven-plugin</packaging>
|
||||
|
||||
@@ -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 -X -Dformat=ALL
|
||||
32
dependency-check-maven/src/it/710-pom-parse-error/pom.xml
Normal file
32
dependency-check-maven/src/it/710-pom-parse-error/pom.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?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>pom-parse-error</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>qdox</groupId>
|
||||
<artifactId>qdox</artifactId>
|
||||
<version>1.6.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -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,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.
|
||||
*/
|
||||
@@ -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);
|
||||
|
||||
@@ -1069,35 +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(), p.getGroupId(), p.getArtifactId(), p.getVersion(),
|
||||
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,19 +100,19 @@ 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);
|
||||
}
|
||||
exCol = ex;
|
||||
}
|
||||
if (exCol == null || !exCol.isFatal()) {
|
||||
try {
|
||||
writeReports(engine, getProject(), getCorrectOutputDirectory());
|
||||
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) {
|
||||
|
||||
@@ -21,7 +21,7 @@ Copyright (c) 2017 Jeremy Long. All Rights Reserved.
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.4.6-SNAPSHOT</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-plugin</artifactId>
|
||||
|
||||
@@ -20,7 +20,7 @@ Copyright (c) 2014 - Jeremy Long. All Rights Reserved.
|
||||
<parent>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.4.6-SNAPSHOT</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dependency-check-utils</artifactId>
|
||||
|
||||
31
pom.xml
31
pom.xml
@@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long
|
||||
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-parent</artifactId>
|
||||
<version>1.4.6-SNAPSHOT</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
@@ -288,7 +288,7 @@ Copyright (c) 2012 - Jeremy Long
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!--destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile-->
|
||||
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
|
||||
<propertyName>surefireArgLine</propertyName>
|
||||
</configuration>
|
||||
</execution>
|
||||
@@ -299,12 +299,31 @@ Copyright (c) 2012 - Jeremy Long
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!--destFile>${project.build.directory}/coverage-reports/jacoco-it.exec</destFile-->
|
||||
<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>
|
||||
@@ -459,7 +478,7 @@ Copyright (c) 2012 - Jeremy Long
|
||||
<configuration>
|
||||
<signature>
|
||||
<groupId>org.codehaus.mojo.signature</groupId>
|
||||
<artifactId>java16</artifactId>
|
||||
<artifactId>java17</artifactId>
|
||||
<version>1.1</version>
|
||||
</signature>
|
||||
</configuration>
|
||||
@@ -578,6 +597,10 @@ Copyright (c) 2012 - Jeremy Long
|
||||
<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>
|
||||
|
||||
@@ -12,4 +12,6 @@
|
||||
<suppress checks=".*" files=".*[\\/]maven-plugin-plugin-sources[\\/].*.properties" />
|
||||
<!--suppress checks=".*" files=".*[\\/]org[\\/]owasp[\\/]dependencycheck[\\/]org[\\/]apache[\\/].*.java" /-->
|
||||
<suppress checks="RegexpHeader" files=".*[\\/]org[\\/]owasp[\\/]dependencycheck[\\/]utils[\\/]SSLSocketFactoryEx.java" />
|
||||
<suppress checks="RegexpHeader" files=".*[\\/]org[\\/]owasp[\\/]dependencycheck[\\/]xml[\\/]XmlInputStream.java" />
|
||||
<suppress checks="RegexpHeader" files=".*[\\/]org[\\/]owasp[\\/]dependencycheck[\\/]xml[\\/]XmlEntity.java" />
|
||||
</suppressions>
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user