All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.owasp.dependencycheck.agent.DependencyCheckScanAgent Maven / Gradle / Ivy

/*
 * 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.
 *
 * 

Example:

*
 * 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();
 * 
* * @author Steve Springett */ @SuppressWarnings("unused") @NotThreadSafe public class DependencyCheckScanAgent { // /** * 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 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; /** * 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; // // /** * 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 getDependencies() { return dependencies; } /** * Sets the list of dependencies to scan. * * @param dependencies new value of dependencies */ public void setDependencies(List 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 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; } // /** * Executes the Dependency-Check on the dependent libraries. Note, * 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); } /** * 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.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(": "); ids.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); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy