DependencyCheckScanAgent.java
- /*
- * This file is part of dependency-check-core.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Copyright (c) 2014 Steve Springett. All Rights Reserved.
- */
- package org.owasp.dependencycheck.agent;
- import java.io.File;
- import java.io.IOException;
- import java.util.List;
- import java.util.stream.Collectors;
- import java.util.stream.Stream;
- import javax.annotation.concurrent.NotThreadSafe;
- import org.owasp.dependencycheck.Engine;
- import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
- import org.owasp.dependencycheck.data.update.exception.UpdateException;
- import org.owasp.dependencycheck.dependency.Dependency;
- import org.owasp.dependencycheck.dependency.Vulnerability;
- import org.owasp.dependencycheck.dependency.naming.Identifier;
- import org.owasp.dependencycheck.exception.ExceptionCollection;
- import org.owasp.dependencycheck.exception.ReportException;
- import org.owasp.dependencycheck.exception.ScanAgentException;
- import org.owasp.dependencycheck.reporting.ReportGenerator;
- import org.owasp.dependencycheck.utils.Settings;
- import org.owasp.dependencycheck.utils.SeverityUtil;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- /**
- * This class provides a way to easily conduct a scan solely based on existing
- * evidence metadata rather than collecting evidence from the files themselves.
- * This class is based on the Ant task and Maven plugin with the exception that
- * it takes a list of dependencies that can be programmatically added from data
- * in a spreadsheet, database or some other datasource and conduct a scan based
- * on this pre-defined evidence.
- *
- * <h2>Example:</h2>
- * <pre>
- * List<Dependency> dependencies = new ArrayList<Dependency>();
- * Dependency dependency = new Dependency(new File(FileUtils.getBitBucket()));
- * dependency.addEvidence(EvidenceType.PRODUCT, "my-datasource", "name", "Jetty", Confidence.HIGH);
- * dependency.addEvidence(EvidenceType.VERSION, "my-datasource", "version", "5.1.10", Confidence.HIGH);
- * dependency.addEvidence(EvidenceType.VENDOR, "my-datasource", "vendor", "mortbay", Confidence.HIGH);
- * dependencies.add(dependency);
- *
- * DependencyCheckScanAgent scan = new DependencyCheckScanAgent();
- * scan.setDependencies(dependencies);
- * scan.setReportFormat(ReportGenerator.Format.ALL);
- * scan.setReportOutputDirectory(System.getProperty("user.home"));
- * scan.execute();
- * </pre>
- *
- * @author Steve Springett
- */
- @SuppressWarnings("unused")
- @NotThreadSafe
- public class DependencyCheckScanAgent {
- //<editor-fold defaultstate="collapsed" desc="private fields">
- /**
- * System specific new line character.
- */
- private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern();
- /**
- * Logger for use throughout the class.
- */
- private static final Logger LOGGER = LoggerFactory.getLogger(DependencyCheckScanAgent.class);
- /**
- * The application name for the report.
- */
- private String applicationName = "Dependency-Check";
- /**
- * The pre-determined dependencies to scan
- */
- private List<Dependency> dependencies;
- /**
- * The location of the data directory that contains
- */
- private String dataDirectory = null;
- /**
- * Specifies the destination directory for the generated Dependency-Check
- * report.
- */
- private String reportOutputDirectory;
- /**
- * Specifies if the build should be failed if a CVSS score above a specified
- * level is identified. The default is 11 which means since the CVSS scores
- * are 0-10, by default the build will never fail and the CVSS score is set
- * to 11. The valid range for the fail build on CVSS is 0 to 11, where
- * anything above 10 will not cause the build to fail.
- */
- private Double failBuildOnCVSS = 11.0;
- /**
- * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not
- * recommended that this be turned to false. Default is true.
- */
- private boolean autoUpdate = true;
- /**
- * The NVD API key.
- */
- private String nvdApiKey;
- /**
- * Sets whether the data directory should be updated without performing a
- * scan. Default is false.
- */
- private boolean updateOnly = false;
- /**
- * flag indicating whether to generate a report of findings.
- */
- private boolean generateReport = true;
- /**
- * The report format to be generated (HTML, XML, CSV, JSON, JUNIT, SARIF,
- * JENKINS, GITLAB, ALL). This configuration option has no affect if using
- * this within the Site plugin unless the externalReport is set to true.
- * Default is HTML.
- */
- private ReportGenerator.Format reportFormat = ReportGenerator.Format.HTML;
- /**
- * The Proxy Server.
- */
- private String proxyServer;
- /**
- * The Proxy Port.
- */
- private String proxyPort;
- /**
- * The Proxy username.
- */
- private String proxyUsername;
- /**
- * The Proxy password.
- */
- private String proxyPassword;
- /**
- * The Connection Timeout.
- */
- private String connectionTimeout;
- /**
- * The Connection Read Timeout.
- */
- private String readTimeout;
- /**
- * The file path used for verbose logging.
- */
- private String logFile = null;
- /**
- * flag indicating whether to show a summary of findings.
- */
- private boolean showSummary = true;
- /**
- * The path to the suppression file.
- */
- private String suppressionFile;
- /**
- * The password to use when connecting to the database.
- */
- private String databasePassword;
- /**
- * The starting string that identifies CPEs that are qualified to be
- * imported.
- */
- private String cpeStartsWithFilter;
- /**
- * Whether the Maven Central analyzer is enabled.
- */
- private boolean centralAnalyzerEnabled = true;
- /**
- * Whether the build should fail if there are unused suppression rules.
- */
- private boolean failOnUnusedSuppressionRule = false;
- /**
- * The URL of Maven Central.
- */
- private String centralUrl;
- /**
- * Whether the nexus analyzer is enabled.
- */
- private boolean nexusAnalyzerEnabled = true;
- /**
- * The URL of the Nexus server.
- */
- private String nexusUrl;
- /**
- * Whether the defined proxy should be used when connecting to Nexus.
- */
- private boolean nexusUsesProxy = true;
- /**
- * The database driver name; such as org.h2.Driver.
- */
- private String databaseDriverName;
- /**
- * The path to the database driver JAR file if it is not on the class path.
- */
- private String databaseDriverPath;
- /**
- * The database connection string.
- */
- private String connectionString;
- /**
- * The username for connecting to the database.
- */
- private String databaseUser;
- /**
- * Additional ZIP File extensions to add analyze. This should be a
- * comma-separated list of file extensions to treat like ZIP files.
- */
- private String zipExtensions;
- /**
- * The path to dotnet core for .NET assembly analysis.
- */
- private String pathToCore;
- /**
- * The configured settings.
- */
- private Settings settings;
- /**
- * The path to optional dependency-check properties file. This will be used
- * to side-load additional user-defined properties.
- * {@link Settings#mergeProperties(String)}
- */
- private String propertiesFilePath;
- //</editor-fold>
- //<editor-fold defaultstate="collapsed" desc="getters/setters">
- /**
- * Get the value of applicationName.
- *
- * @return the value of applicationName
- */
- public String getApplicationName() {
- return applicationName;
- }
- /**
- * Set the value of applicationName.
- *
- * @param applicationName new value of applicationName
- */
- public void setApplicationName(String applicationName) {
- this.applicationName = applicationName;
- }
- /**
- * Get the value of nvdApiKey.
- *
- * @return the value of nvdApiKey
- */
- public String getNvdApiKey() {
- return nvdApiKey;
- }
- /**
- * Set the value of nvdApiKey.
- *
- * @param nvdApiKey new value of nvdApiKey
- */
- public void setNvdApiKey(String nvdApiKey) {
- this.nvdApiKey = nvdApiKey;
- }
- /**
- * Returns a list of pre-determined dependencies.
- *
- * @return returns a list of dependencies
- */
- public List<Dependency> getDependencies() {
- return dependencies;
- }
- /**
- * Sets the list of dependencies to scan.
- *
- * @param dependencies new value of dependencies
- */
- public void setDependencies(List<Dependency> dependencies) {
- this.dependencies = dependencies;
- }
- /**
- * Get the value of dataDirectory.
- *
- * @return the value of dataDirectory
- */
- public String getDataDirectory() {
- return dataDirectory;
- }
- /**
- * Set the value of dataDirectory.
- *
- * @param dataDirectory new value of dataDirectory
- */
- public void setDataDirectory(String dataDirectory) {
- this.dataDirectory = dataDirectory;
- }
- /**
- * Get the value of reportOutputDirectory.
- *
- * @return the value of reportOutputDirectory
- */
- public String getReportOutputDirectory() {
- return reportOutputDirectory;
- }
- /**
- * Set the value of reportOutputDirectory.
- *
- * @param reportOutputDirectory new value of reportOutputDirectory
- */
- public void setReportOutputDirectory(String reportOutputDirectory) {
- this.reportOutputDirectory = reportOutputDirectory;
- }
- /**
- * Get the value of failBuildOnCVSS.
- *
- * @return the value of failBuildOnCVSS
- */
- public Double getFailBuildOnCVSS() {
- return failBuildOnCVSS;
- }
- /**
- * Set the value of failBuildOnCVSS.
- *
- * @param failBuildOnCVSS new value of failBuildOnCVSS
- */
- public void setFailBuildOnCVSS(Double failBuildOnCVSS) {
- this.failBuildOnCVSS = failBuildOnCVSS;
- }
- /**
- * Get the value of autoUpdate.
- *
- * @return the value of autoUpdate
- */
- public boolean isAutoUpdate() {
- return autoUpdate;
- }
- /**
- * Set the value of autoUpdate.
- *
- * @param autoUpdate new value of autoUpdate
- */
- public void setAutoUpdate(boolean autoUpdate) {
- this.autoUpdate = autoUpdate;
- }
- /**
- * Get the value of updateOnly.
- *
- * @return the value of updateOnly
- */
- public boolean isUpdateOnly() {
- return updateOnly;
- }
- /**
- * Set the value of updateOnly.
- *
- * @param updateOnly new value of updateOnly
- */
- public void setUpdateOnly(boolean updateOnly) {
- this.updateOnly = updateOnly;
- }
- /**
- * Get the value of generateReport.
- *
- * @return the value of generateReport
- */
- public boolean isGenerateReport() {
- return generateReport;
- }
- /**
- * Set the value of generateReport.
- *
- * @param generateReport new value of generateReport
- */
- public void setGenerateReport(boolean generateReport) {
- this.generateReport = generateReport;
- }
- /**
- * Get the value of reportFormat.
- *
- * @return the value of reportFormat
- */
- public ReportGenerator.Format getReportFormat() {
- return reportFormat;
- }
- /**
- * Set the value of reportFormat.
- *
- * @param reportFormat new value of reportFormat
- */
- public void setReportFormat(ReportGenerator.Format reportFormat) {
- this.reportFormat = reportFormat;
- }
- /**
- * Get the value of proxyServer.
- *
- * @return the value of proxyServer
- */
- public String getProxyServer() {
- return proxyServer;
- }
- /**
- * Set the value of proxyServer.
- *
- * @param proxyServer new value of proxyServer
- */
- public void setProxyServer(String proxyServer) {
- this.proxyServer = proxyServer;
- }
- /**
- * Get the value of proxyServer.
- *
- * @return the value of proxyServer
- * @deprecated use
- * {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#getProxyServer()}
- * instead
- */
- @Deprecated
- public String getProxyUrl() {
- return proxyServer;
- }
- /**
- * Set the value of proxyServer.
- *
- * @param proxyUrl new value of proxyServer
- * @deprecated use {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#setProxyServer(java.lang.String)
- * } instead
- */
- @Deprecated
- public void setProxyUrl(String proxyUrl) {
- this.proxyServer = proxyUrl;
- }
- /**
- * Get the value of proxyPort.
- *
- * @return the value of proxyPort
- */
- public String getProxyPort() {
- return proxyPort;
- }
- /**
- * Set the value of proxyPort.
- *
- * @param proxyPort new value of proxyPort
- */
- public void setProxyPort(String proxyPort) {
- this.proxyPort = proxyPort;
- }
- /**
- * Get the value of proxyUsername.
- *
- * @return the value of proxyUsername
- */
- public String getProxyUsername() {
- return proxyUsername;
- }
- /**
- * Set the value of proxyUsername.
- *
- * @param proxyUsername new value of proxyUsername
- */
- public void setProxyUsername(String proxyUsername) {
- this.proxyUsername = proxyUsername;
- }
- /**
- * Get the value of proxyPassword.
- *
- * @return the value of proxyPassword
- */
- public String getProxyPassword() {
- return proxyPassword;
- }
- /**
- * Set the value of proxyPassword.
- *
- * @param proxyPassword new value of proxyPassword
- */
- public void setProxyPassword(String proxyPassword) {
- this.proxyPassword = proxyPassword;
- }
- /**
- * Get the value of connectionTimeout.
- *
- * @return the value of connectionTimeout
- */
- public String getConnectionTimeout() {
- return connectionTimeout;
- }
- /**
- * Set the value of connectionTimeout.
- *
- * @param connectionTimeout new value of connectionTimeout
- */
- public void setConnectionTimeout(String connectionTimeout) {
- this.connectionTimeout = connectionTimeout;
- }
- /**
- * Get the value of readTimeout.
- *
- * @return the value of readTimeout
- */
- public String getReadTimeout() {
- return readTimeout;
- }
- /**
- * Set the value of readTimeout.
- *
- * @param readTimeout new value of readTimeout
- */
- public void setReadTimeout(String readTimeout) {
- this.readTimeout = readTimeout;
- }
- /**
- * Get the value of logFile.
- *
- * @return the value of logFile
- */
- public String getLogFile() {
- return logFile;
- }
- /**
- * Set the value of logFile.
- *
- * @param logFile new value of logFile
- */
- public void setLogFile(String logFile) {
- this.logFile = logFile;
- }
- /**
- * Get the value of suppressionFile.
- *
- * @return the value of suppressionFile
- */
- public String getSuppressionFile() {
- return suppressionFile;
- }
- /**
- * Set the value of suppressionFile.
- *
- * @param suppressionFile new value of suppressionFile
- */
- public void setSuppressionFile(String suppressionFile) {
- this.suppressionFile = suppressionFile;
- }
- /**
- * Get the value of showSummary.
- *
- * @return the value of showSummary
- */
- public boolean isShowSummary() {
- return showSummary;
- }
- /**
- * Set the value of showSummary.
- *
- * @param showSummary new value of showSummary
- */
- public void setShowSummary(boolean showSummary) {
- this.showSummary = showSummary;
- }
- /**
- * Sets starting string that identifies CPEs that are qualified to be
- * imported.
- *
- * @param cpeStartsWithFilter filters CPEs based on this starting string
- * (i.e. cpe:/a: )
- */
- public void setCpeStartsWithFilter(String cpeStartsWithFilter) {
- this.cpeStartsWithFilter = cpeStartsWithFilter;
- }
- /**
- * Returns the starting string that identifies CPEs that are qualified to be
- * imported.
- *
- * @return the CPE starting filter (i.e. cpe:/a: )
- */
- public String getCpeStartsWithFilter() {
- return cpeStartsWithFilter;
- }
- /**
- * Get the value of failOnUnusedSuppressionRule.
- *
- * @return the value of failOnUnusedSuppressionRule
- */
- public boolean isFailOnUnusedSuppressionRule() {
- return failOnUnusedSuppressionRule;
- }
- /**
- * Set the value of failOnUnusedSuppressionRule.
- *
- * @param failOnUnusedSuppressionRule new value of failOnUnusedSuppressionRule
- */
- public void setFailOnUnusedSuppressionRule(boolean failOnUnusedSuppressionRule) {
- this.failOnUnusedSuppressionRule = failOnUnusedSuppressionRule;
- }
- /**
- * Get the value of centralAnalyzerEnabled.
- *
- * @return the value of centralAnalyzerEnabled
- */
- public boolean isCentralAnalyzerEnabled() {
- return centralAnalyzerEnabled;
- }
- /**
- * Set the value of centralAnalyzerEnabled.
- *
- * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled
- */
- public void setCentralAnalyzerEnabled(boolean centralAnalyzerEnabled) {
- this.centralAnalyzerEnabled = centralAnalyzerEnabled;
- }
- /**
- * Get the value of centralUrl.
- *
- * @return the value of centralUrl
- */
- public String getCentralUrl() {
- return centralUrl;
- }
- /**
- * Set the value of centralUrl.
- *
- * @param centralUrl new value of centralUrl
- */
- public void setCentralUrl(String centralUrl) {
- this.centralUrl = centralUrl;
- }
- /**
- * Get the value of nexusAnalyzerEnabled.
- *
- * @return the value of nexusAnalyzerEnabled
- */
- public boolean isNexusAnalyzerEnabled() {
- return nexusAnalyzerEnabled;
- }
- /**
- * Set the value of nexusAnalyzerEnabled.
- *
- * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled
- */
- public void setNexusAnalyzerEnabled(boolean nexusAnalyzerEnabled) {
- this.nexusAnalyzerEnabled = nexusAnalyzerEnabled;
- }
- /**
- * Get the value of nexusUrl.
- *
- * @return the value of nexusUrl
- */
- public String getNexusUrl() {
- return nexusUrl;
- }
- /**
- * Set the value of nexusUrl.
- *
- * @param nexusUrl new value of nexusUrl
- */
- public void setNexusUrl(String nexusUrl) {
- this.nexusUrl = nexusUrl;
- }
- /**
- * Get the value of nexusUsesProxy.
- *
- * @return the value of nexusUsesProxy
- */
- public boolean isNexusUsesProxy() {
- return nexusUsesProxy;
- }
- /**
- * Set the value of nexusUsesProxy.
- *
- * @param nexusUsesProxy new value of nexusUsesProxy
- */
- public void setNexusUsesProxy(boolean nexusUsesProxy) {
- this.nexusUsesProxy = nexusUsesProxy;
- }
- /**
- * Get the value of databaseDriverName.
- *
- * @return the value of databaseDriverName
- */
- public String getDatabaseDriverName() {
- return databaseDriverName;
- }
- /**
- * Set the value of databaseDriverName.
- *
- * @param databaseDriverName new value of databaseDriverName
- */
- public void setDatabaseDriverName(String databaseDriverName) {
- this.databaseDriverName = databaseDriverName;
- }
- /**
- * Get the value of databaseDriverPath.
- *
- * @return the value of databaseDriverPath
- */
- public String getDatabaseDriverPath() {
- return databaseDriverPath;
- }
- /**
- * Set the value of databaseDriverPath.
- *
- * @param databaseDriverPath new value of databaseDriverPath
- */
- public void setDatabaseDriverPath(String databaseDriverPath) {
- this.databaseDriverPath = databaseDriverPath;
- }
- /**
- * Get the value of connectionString.
- *
- * @return the value of connectionString
- */
- public String getConnectionString() {
- return connectionString;
- }
- /**
- * Set the value of connectionString.
- *
- * @param connectionString new value of connectionString
- */
- public void setConnectionString(String connectionString) {
- this.connectionString = connectionString;
- }
- /**
- * Get the value of databaseUser.
- *
- * @return the value of databaseUser
- */
- public String getDatabaseUser() {
- return databaseUser;
- }
- /**
- * Set the value of databaseUser.
- *
- * @param databaseUser new value of databaseUser
- */
- public void setDatabaseUser(String databaseUser) {
- this.databaseUser = databaseUser;
- }
- /**
- * Get the value of databasePassword.
- *
- * @return the value of databasePassword
- */
- public String getDatabasePassword() {
- return databasePassword;
- }
- /**
- * Set the value of databasePassword.
- *
- * @param databasePassword new value of databasePassword
- */
- public void setDatabasePassword(String databasePassword) {
- this.databasePassword = databasePassword;
- }
- /**
- * Get the value of zipExtensions.
- *
- * @return the value of zipExtensions
- */
- public String getZipExtensions() {
- return zipExtensions;
- }
- /**
- * Set the value of zipExtensions.
- *
- * @param zipExtensions new value of zipExtensions
- */
- public void setZipExtensions(String zipExtensions) {
- this.zipExtensions = zipExtensions;
- }
- /**
- * Get the value of pathToCore.
- *
- * @return the value of pathToCore
- */
- public String getPathToDotnetCore() {
- return pathToCore;
- }
- /**
- * Set the value of pathToCore.
- *
- * @param pathToCore new value of pathToCore
- */
- public void setPathToDotnetCore(String pathToCore) {
- this.pathToCore = pathToCore;
- }
- /**
- * Get the value of propertiesFilePath.
- *
- * @return the value of propertiesFilePath
- */
- public String getPropertiesFilePath() {
- return propertiesFilePath;
- }
- /**
- * Set the value of propertiesFilePath.
- *
- * @param propertiesFilePath new value of propertiesFilePath
- */
- public void setPropertiesFilePath(String propertiesFilePath) {
- this.propertiesFilePath = propertiesFilePath;
- }
- //</editor-fold>
- /**
- * Executes the Dependency-Check on the dependent libraries. <b>Note</b>,
- * the engine object returned from this method must be closed by calling
- * `close()`
- *
- * @return the Engine used to scan the dependencies.
- * @throws ExceptionCollection a collection of one or more exceptions that
- * occurred during analysis.
- */
- @SuppressWarnings("squid:S2095")
- private Engine executeDependencyCheck() throws ExceptionCollection {
- populateSettings();
- final Engine engine;
- try {
- engine = new Engine(settings);
- } catch (DatabaseException ex) {
- throw new ExceptionCollection(ex, true);
- }
- if (this.updateOnly) {
- try {
- engine.doUpdates();
- } catch (UpdateException ex) {
- throw new ExceptionCollection(ex);
- } finally {
- engine.close();
- }
- } else {
- engine.setDependencies(this.dependencies);
- engine.analyzeDependencies();
- }
- return engine;
- }
- /**
- * Generates the reports for a given dependency-check engine.
- *
- * @param engine a dependency-check engine
- * @param outDirectory the directory to write the reports to
- * @throws ScanAgentException thrown if there is an error generating the
- * report
- */
- private void generateExternalReports(Engine engine, File outDirectory) throws ScanAgentException {
- try {
- engine.writeReports(applicationName, outDirectory, this.reportFormat.name(), null);
- } 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);
- }
- }
- /**
- * Takes the properties supplied and updates the dependency-check settings.
- * Additionally, this sets the system properties required to change the
- * proxy server, port, and connection timeout.
- */
- private void populateSettings() {
- settings = new Settings();
- if (dataDirectory != null) {
- settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
- } else {
- final File jarPath = new File(DependencyCheckScanAgent.class.getProtectionDomain().getCodeSource().getLocation().getPath());
- final File base = jarPath.getParentFile();
- final String sub = settings.getString(Settings.KEYS.DATA_DIRECTORY);
- final File dataDir = new File(base, sub);
- settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
- }
- if (propertiesFilePath != null) {
- try {
- settings.mergeProperties(propertiesFilePath);
- LOGGER.info("Successfully loaded user-defined properties");
- } catch (IOException e) {
- LOGGER.error("Unable to merge user-defined properties", e);
- LOGGER.error("Continuing execution");
- }
- }
- settings.setBoolean(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, proxyUsername);
- settings.setStringIfNotEmpty(Settings.KEYS.PROXY_PASSWORD, proxyPassword);
- settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
- settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_READ_TIMEOUT, readTimeout);
- settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
- settings.setStringIfNotEmpty(Settings.KEYS.CVE_CPE_STARTS_WITH_FILTER, cpeStartsWithFilter);
- settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled);
- settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_CENTRAL_URL, centralUrl);
- settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
- settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
- settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
- settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
- settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
- settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
- settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
- settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
- settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
- settings.setStringIfNotEmpty(Settings.KEYS.NVD_API_KEY, nvdApiKey);
- settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_DOTNET_PATH, pathToCore);
- settings.setBoolean(Settings.KEYS.FAIL_ON_UNUSED_SUPPRESSION_RULE, failOnUnusedSuppressionRule);
- }
- /**
- * Executes the dependency-check and generates the report.
- *
- * @return a reference to the engine used to perform the scan.
- * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if
- * there is an exception executing the scan.
- */
- public Engine execute() throws ScanAgentException {
- Engine engine = null;
- try {
- engine = executeDependencyCheck();
- if (!this.updateOnly) {
- if (this.generateReport) {
- generateExternalReports(engine, new File(this.reportOutputDirectory));
- }
- if (this.showSummary) {
- showSummary(engine.getDependencies());
- }
- if (this.failBuildOnCVSS <= 10.0) {
- checkForFailure(engine.getDependencies());
- }
- }
- } catch (ExceptionCollection ex) {
- if (ex.isFatal()) {
- LOGGER.error("A fatal exception occurred during analysis; analysis has stopped. Please see the debug log for more details.");
- LOGGER.debug("", ex);
- }
- throw new ScanAgentException("One or more exceptions occurred during analysis; please see the debug log for more details.", ex);
- } finally {
- if (engine != null) {
- engine.close();
- }
- settings.cleanup(true);
- }
- return engine;
- }
- /**
- * Checks to see if a vulnerability has been identified with a CVSS score
- * that is above the threshold set in the configuration.
- *
- * @param dependencies the list of dependency objects
- * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if
- * there is an exception executing the scan.
- */
- private void checkForFailure(Dependency[] dependencies) throws ScanAgentException {
- final StringBuilder ids = new StringBuilder();
- for (Dependency d : dependencies) {
- boolean addName = true;
- for (Vulnerability v : d.getVulnerabilities()) {
- if ((v.getCvssV2() != null && v.getCvssV2().getCvssData().getBaseScore() >= failBuildOnCVSS)
- || (v.getCvssV3() != null && v.getCvssV3().getCvssData().getBaseScore() >= failBuildOnCVSS)
- || (v.getCvssV4() != null && v.getCvssV4().getCvssData().getBaseScore() >= failBuildOnCVSS)
- || (v.getUnscoredSeverity() != null && SeverityUtil.estimateCvssV2(v.getUnscoredSeverity()) >= failBuildOnCVSS)
- //safety net to fail on any if for some reason the above misses on 0
- || (failBuildOnCVSS <= 0.0f)) {
- if (addName) {
- addName = false;
- ids.append(NEW_LINE).append(d.getFileName()).append(" (")
- .append(Stream.concat(d.getSoftwareIdentifiers().stream(), d.getVulnerableSoftwareIdentifiers().stream())
- .map(Identifier::getValue)
- .collect(Collectors.joining(", ")))
- .append("): ")
- .append(v.getName());
- } else {
- ids.append(", ").append(v.getName());
- }
- }
- }
- }
- if (ids.length() > 0) {
- final String msg;
- if (showSummary) {
- msg = String.format("%n%nDependency-Check Failure:%n"
- + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater than or equal to '%.1f': %s%n"
- + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids);
- } else {
- msg = String.format("%n%nDependency-Check Failure:%n"
- + "One or more dependencies were identified with vulnerabilities.%n%n"
- + "See the dependency-check report for more details.%n%n");
- }
- throw new ScanAgentException(msg);
- }
- }
- /**
- * Generates a warning message listing a summary of dependencies and their
- * associated CPE and CVE entries.
- *
- * @param dependencies a list of dependency objects
- */
- public static void showSummary(Dependency[] dependencies) {
- showSummary(null, dependencies);
- }
- /**
- * Generates a warning message listing a summary of dependencies and their
- * associated CPE and CVE entries.
- *
- * @param projectName the name of the project
- * @param dependencies a list of dependency objects
- */
- public static void showSummary(String projectName, Dependency[] dependencies) {
- final StringBuilder summary = new StringBuilder();
- for (Dependency d : dependencies) {
- final String ids = d.getVulnerabilities(true).stream()
- .map(Vulnerability::getName)
- .collect(Collectors.joining(", "));
- if (ids.length() > 0) {
- summary.append(d.getFileName()).append(" (");
- summary.append(Stream.concat(d.getSoftwareIdentifiers().stream(), d.getVulnerableSoftwareIdentifiers().stream())
- .map(Identifier::getValue)
- .collect(Collectors.joining(", ")));
- summary.append(") : ").append(ids).append(NEW_LINE);
- }
- }
- if (summary.length() > 0) {
- if (projectName == null || projectName.isEmpty()) {
- LOGGER.warn("\n\nOne or more dependencies were identified with known vulnerabilities:\n\n{}\n\n"
- + "See the dependency-check report for more details.\n\n",
- summary);
- } else {
- LOGGER.warn("\n\nOne or more dependencies were identified with known vulnerabilities in {}:\n\n{}\n\n"
- + "See the dependency-check report for more details.\n\n",
- projectName,
- summary);
- }
- }
- }
- }