/* * This file is part of dependency-check-ant. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Copyright (c) 2013 Jeremy Long. All Rights Reserved. */ package org.owasp.dependencycheck.taskdefs; import java.io.File; import java.util.List; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.EnumeratedAttribute; import org.apache.tools.ant.types.Reference; import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.ResourceCollection; import org.apache.tools.ant.types.resources.FileProvider; import org.apache.tools.ant.types.resources.Resources; 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.data.update.exception.UpdateException; import org.owasp.dependencycheck.dependency.Dependency; import org.owasp.dependencycheck.dependency.Identifier; import org.owasp.dependencycheck.dependency.Vulnerability; import org.owasp.dependencycheck.exception.ExceptionCollection; import org.owasp.dependencycheck.exception.ReportException; import org.owasp.dependencycheck.reporting.ReportGenerator; import org.owasp.dependencycheck.reporting.ReportGenerator.Format; import org.owasp.dependencycheck.utils.Settings; import org.slf4j.impl.StaticLoggerBinder; /** * An Ant task definition to execute dependency-check during an Ant build. * * @author Jeremy Long */ public class Check extends Update { /** * System specific new line character. */ private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern(); /** * Whether the ruby gemspec analyzer should be enabled. */ private Boolean rubygemsAnalyzerEnabled; /** * Whether or not the Node.js Analyzer is enabled. */ private Boolean nodeAnalyzerEnabled; /** * Whether or not the Ruby Bundle Audit Analyzer is enabled. */ private Boolean bundleAuditAnalyzerEnabled; /** * Whether the CMake analyzer should be enabled. */ private Boolean cmakeAnalyzerEnabled; /** * Whether or not the Open SSL analyzer is enabled. */ private Boolean opensslAnalyzerEnabled; /** * Whether the python package analyzer should be enabled. */ private Boolean pyPackageAnalyzerEnabled; /** * Whether the python distribution analyzer should be enabled. */ private Boolean pyDistributionAnalyzerEnabled; /** * Whether or not the central analyzer is enabled. */ private Boolean centralAnalyzerEnabled; /** * Whether or not the nexus analyzer is enabled. */ private Boolean nexusAnalyzerEnabled; /** * The URL of a Nexus server's REST API end point * (http://domain/nexus/service/local). */ private String nexusUrl; /** * Whether or not the defined proxy should be used when connecting to Nexus. */ private Boolean nexusUsesProxy; /** * 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 Mono for .NET assembly analysis on non-windows systems. */ private String pathToMono; /** * The application name for the report. * * @deprecated use projectName instead. */ @Deprecated private String applicationName = null; /** * The name of the project being analyzed. */ private String projectName = "dependency-check"; /** * 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 float failBuildOnCVSS = 11; /** * 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; /** * Whether only the update phase should be executed. * * @deprecated Use the update task instead */ @Deprecated private boolean updateOnly = false; /** * The report format to be generated (HTML, XML, VULN, CSV, JSON, ALL). Default is * HTML. */ private String reportFormat = "HTML"; /** * The path to the suppression file. */ private String suppressionFile; /** * The path to the suppression file. */ private String hintsFile; /** * flag indicating whether or not to show a summary of findings. */ private boolean showSummary = true; /** * Whether experimental analyzers are enabled. */ private Boolean enableExperimental; /** * Whether or not the Jar Analyzer is enabled. */ private Boolean jarAnalyzerEnabled; /** * Whether or not the Archive Analyzer is enabled. */ private Boolean archiveAnalyzerEnabled; /** * Whether or not the .NET Nuspec Analyzer is enabled. */ private Boolean nuspecAnalyzerEnabled; /** * Whether or not the PHP Composer Analyzer is enabled. */ private Boolean composerAnalyzerEnabled; /** * Whether or not the .NET Assembly Analyzer is enabled. */ private Boolean assemblyAnalyzerEnabled; /** * Whether the autoconf analyzer should be enabled. */ private Boolean autoconfAnalyzerEnabled; /** * Sets the path for the bundle-audit binary. */ private String bundleAuditPath; /** * Whether or not the CocoaPods Analyzer is enabled. */ private Boolean cocoapodsAnalyzerEnabled; /** * Whether or not the Swift package Analyzer is enabled. */ private Boolean swiftPackageManagerAnalyzerEnabled; //The following code was copied Apache Ant PathConvert //BEGIN COPY from org.apache.tools.ant.taskdefs.PathConvert /** * Path to be converted */ private Resources path = null; /** * Reference to path/file set to convert */ private Reference refId = null; /** * Add an arbitrary ResourceCollection. * * @param rc the ResourceCollection to add. * @since Ant 1.7 */ public void add(ResourceCollection rc) { if (isReference()) { throw new BuildException("Nested elements are not allowed when using the refId attribute."); } getPath().add(rc); } /** * Returns the path. If the path has not been initialized yet, this class is * synchronized, and will instantiate the path object. * * @return the path */ private synchronized Resources getPath() { if (path == null) { path = new Resources(getProject()); path.setCache(true); } return path; } /** * Learn whether the refId attribute of this element been set. * * @return true if refId is valid. */ public boolean isReference() { return refId != null; } /** * Add a reference to a Path, FileSet, DirSet, or FileList defined * elsewhere. * * @param r the reference to a path, fileset, dirset or filelist. */ public synchronized void setRefId(Reference r) { if (path != null) { throw new BuildException("Nested elements are not allowed when using the refId attribute."); } refId = r; } /** * If this is a reference, this method will add the referenced resource * collection to the collection of paths. * * @throws BuildException if the reference is not to a resource collection */ private void dealWithReferences() throws BuildException { if (isReference()) { final Object o = refId.getReferencedObject(getProject()); if (!(o instanceof ResourceCollection)) { throw new BuildException("refId '" + refId.getRefId() + "' does not refer to a resource collection."); } getPath().add((ResourceCollection) o); } } // END COPY from org.apache.tools.ant.taskdefs /** * Construct a new DependencyCheckTask. */ public Check() { super(); // Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from // core end up coming through this tasks logger StaticLoggerBinder.getSingleton().setTask(this); } /** * Get the value of applicationName. * * @return the value of applicationName * * @deprecated use projectName instead. */ @Deprecated public String getApplicationName() { return applicationName; } /** * Set the value of applicationName. * * @param applicationName new value of applicationName * @deprecated use projectName instead. */ @Deprecated public void setApplicationName(String applicationName) { this.applicationName = applicationName; } /** * Get the value of projectName. * * @return the value of projectName */ public String getProjectName() { if (applicationName != null) { log("Configuration 'applicationName' has been deprecated, please use 'projectName' instead", Project.MSG_WARN); if ("dependency-check".equals(projectName)) { projectName = applicationName; } } return projectName; } /** * Set the value of projectName. * * @param projectName new value of projectName */ public void setProjectName(String projectName) { this.projectName = projectName; } /** * 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 float getFailBuildOnCVSS() { return failBuildOnCVSS; } /** * Set the value of failBuildOnCVSS. * * @param failBuildOnCVSS new value of failBuildOnCVSS */ public void setFailBuildOnCVSS(float 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 * @deprecated Use the update task instead */ @Deprecated public boolean isUpdateOnly() { return updateOnly; } /** * Set the value of updateOnly. * * @param updateOnly new value of updateOnly * @deprecated Use the update task instead */ @Deprecated public void setUpdateOnly(boolean updateOnly) { this.updateOnly = updateOnly; } /** * Get the value of reportFormat. * * @return the value of reportFormat */ public String getReportFormat() { return reportFormat; } /** * Set the value of reportFormat. * * @param reportFormat new value of reportFormat */ public void setReportFormat(ReportFormats reportFormat) { this.reportFormat = reportFormat.getValue(); } /** * 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 hintsFile. * * @return the value of hintsFile */ public String getHintsFile() { return hintsFile; } /** * Set the value of hintsFile. * * @param hintsFile new value of hintsFile */ public void setHintsFile(String hintsFile) { this.hintsFile = hintsFile; } /** * 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; } /** * Get the value of enableExperimental. * * @return the value of enableExperimental */ public Boolean isEnableExperimental() { return enableExperimental; } /** * Set the value of enableExperimental. * * @param enableExperimental new value of enableExperimental */ public void setEnableExperimental(Boolean enableExperimental) { this.enableExperimental = enableExperimental; } /** * Returns whether or not the analyzer is enabled. * * @return true if the analyzer is enabled */ public Boolean isJarAnalyzerEnabled() { return jarAnalyzerEnabled; } /** * Sets whether or not the analyzer is enabled. * * @param jarAnalyzerEnabled the value of the new setting */ public void setJarAnalyzerEnabled(Boolean jarAnalyzerEnabled) { this.jarAnalyzerEnabled = jarAnalyzerEnabled; } /** * Returns whether or not the analyzer is enabled. * * @return true if the analyzer is enabled */ public Boolean isArchiveAnalyzerEnabled() { return archiveAnalyzerEnabled; } /** * Sets whether or not the analyzer is enabled. * * @param archiveAnalyzerEnabled the value of the new setting */ public void setArchiveAnalyzerEnabled(Boolean archiveAnalyzerEnabled) { this.archiveAnalyzerEnabled = archiveAnalyzerEnabled; } /** * Returns whether or not the analyzer is enabled. * * @return true if the analyzer is enabled */ public Boolean isAssemblyAnalyzerEnabled() { return assemblyAnalyzerEnabled; } /** * Sets whether or not the analyzer is enabled. * * @param assemblyAnalyzerEnabled the value of the new setting */ public void setAssemblyAnalyzerEnabled(Boolean assemblyAnalyzerEnabled) { this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled; } /** * Returns whether or not the analyzer is enabled. * * @return true if the analyzer is enabled */ public Boolean isNuspecAnalyzerEnabled() { return nuspecAnalyzerEnabled; } /** * Sets whether or not the analyzer is enabled. * * @param nuspecAnalyzerEnabled the value of the new setting */ public void setNuspecAnalyzerEnabled(Boolean nuspecAnalyzerEnabled) { this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled; } /** * Get the value of composerAnalyzerEnabled. * * @return the value of composerAnalyzerEnabled */ public Boolean isComposerAnalyzerEnabled() { return composerAnalyzerEnabled; } /** * Set the value of composerAnalyzerEnabled. * * @param composerAnalyzerEnabled new value of composerAnalyzerEnabled */ public void setComposerAnalyzerEnabled(Boolean composerAnalyzerEnabled) { this.composerAnalyzerEnabled = composerAnalyzerEnabled; } /** * Get the value of autoconfAnalyzerEnabled. * * @return the value of autoconfAnalyzerEnabled */ public Boolean isAutoconfAnalyzerEnabled() { return autoconfAnalyzerEnabled; } /** * Set the value of autoconfAnalyzerEnabled. * * @param autoconfAnalyzerEnabled new value of autoconfAnalyzerEnabled */ public void setAutoconfAnalyzerEnabled(Boolean autoconfAnalyzerEnabled) { this.autoconfAnalyzerEnabled = autoconfAnalyzerEnabled; } /** * Get the value of cmakeAnalyzerEnabled. * * @return the value of cmakeAnalyzerEnabled */ public Boolean isCMakeAnalyzerEnabled() { return cmakeAnalyzerEnabled; } /** * Set the value of cmakeAnalyzerEnabled. * * @param cmakeAnalyzerEnabled new value of cmakeAnalyzerEnabled */ public void setCMakeAnalyzerEnabled(Boolean cmakeAnalyzerEnabled) { this.cmakeAnalyzerEnabled = cmakeAnalyzerEnabled; } /** * Returns if the Bundle Audit Analyzer is enabled. * * @return if the Bundle Audit Analyzer is enabled. */ public Boolean isBundleAuditAnalyzerEnabled() { return bundleAuditAnalyzerEnabled; } /** * Sets if the Bundle Audit Analyzer is enabled. * * @param bundleAuditAnalyzerEnabled whether or not the analyzer should be * enabled */ public void setBundleAuditAnalyzerEnabled(Boolean bundleAuditAnalyzerEnabled) { this.bundleAuditAnalyzerEnabled = bundleAuditAnalyzerEnabled; } /** * Returns the path to the bundle audit executable. * * @return the path to the bundle audit executable */ public String getBundleAuditPath() { return bundleAuditPath; } /** * Sets the path to the bundle audit executable. * * @param bundleAuditPath the path to the bundle audit executable */ public void setBundleAuditPath(String bundleAuditPath) { this.bundleAuditPath = bundleAuditPath; } /** * Returns if the cocoapods analyzer is enabled. * * @return if the cocoapods analyzer is enabled */ public boolean isCocoapodsAnalyzerEnabled() { return cocoapodsAnalyzerEnabled; } /** * Sets whether or not the cocoapods analyzer is enabled. * * @param cocoapodsAnalyzerEnabled the state of the cocoapods analyzer */ public void setCocoapodsAnalyzerEnabled(Boolean cocoapodsAnalyzerEnabled) { this.cocoapodsAnalyzerEnabled = cocoapodsAnalyzerEnabled; } /** * Returns whether or not the Swift package Analyzer is enabled. * * @return whether or not the Swift package Analyzer is enabled */ public Boolean isSwiftPackageManagerAnalyzerEnabled() { return swiftPackageManagerAnalyzerEnabled; } /** * Sets the enabled state of the swift package manager analyzer. * * @param swiftPackageManagerAnalyzerEnabled the enabled state of the swift * package manager */ public void setSwiftPackageManagerAnalyzerEnabled(Boolean swiftPackageManagerAnalyzerEnabled) { this.swiftPackageManagerAnalyzerEnabled = swiftPackageManagerAnalyzerEnabled; } /** * Get the value of opensslAnalyzerEnabled. * * @return the value of opensslAnalyzerEnabled */ public Boolean isOpensslAnalyzerEnabled() { return opensslAnalyzerEnabled; } /** * Set the value of opensslAnalyzerEnabled. * * @param opensslAnalyzerEnabled new value of opensslAnalyzerEnabled */ public void setOpensslAnalyzerEnabled(Boolean opensslAnalyzerEnabled) { this.opensslAnalyzerEnabled = opensslAnalyzerEnabled; } /** * Get the value of nodeAnalyzerEnabled. * * @return the value of nodeAnalyzerEnabled */ public Boolean isNodeAnalyzerEnabled() { return nodeAnalyzerEnabled; } /** * Set the value of nodeAnalyzerEnabled. * * @param nodeAnalyzerEnabled new value of nodeAnalyzerEnabled */ public void setNodeAnalyzerEnabled(Boolean nodeAnalyzerEnabled) { this.nodeAnalyzerEnabled = nodeAnalyzerEnabled; } /** * Get the value of rubygemsAnalyzerEnabled. * * @return the value of rubygemsAnalyzerEnabled */ public Boolean isRubygemsAnalyzerEnabled() { return rubygemsAnalyzerEnabled; } /** * Set the value of rubygemsAnalyzerEnabled. * * @param rubygemsAnalyzerEnabled new value of rubygemsAnalyzerEnabled */ public void setRubygemsAnalyzerEnabled(Boolean rubygemsAnalyzerEnabled) { this.rubygemsAnalyzerEnabled = rubygemsAnalyzerEnabled; } /** * Get the value of pyPackageAnalyzerEnabled. * * @return the value of pyPackageAnalyzerEnabled */ public Boolean isPyPackageAnalyzerEnabled() { return pyPackageAnalyzerEnabled; } /** * Set the value of pyPackageAnalyzerEnabled. * * @param pyPackageAnalyzerEnabled new value of pyPackageAnalyzerEnabled */ public void setPyPackageAnalyzerEnabled(Boolean pyPackageAnalyzerEnabled) { this.pyPackageAnalyzerEnabled = pyPackageAnalyzerEnabled; } /** * Get the value of pyDistributionAnalyzerEnabled. * * @return the value of pyDistributionAnalyzerEnabled */ public Boolean isPyDistributionAnalyzerEnabled() { return pyDistributionAnalyzerEnabled; } /** * Set the value of pyDistributionAnalyzerEnabled. * * @param pyDistributionAnalyzerEnabled new value of * pyDistributionAnalyzerEnabled */ public void setPyDistributionAnalyzerEnabled(Boolean pyDistributionAnalyzerEnabled) { this.pyDistributionAnalyzerEnabled = pyDistributionAnalyzerEnabled; } /** * 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 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 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 pathToMono. * * @return the value of pathToMono */ public String getPathToMono() { return pathToMono; } /** * Set the value of pathToMono. * * @param pathToMono new value of pathToMono */ public void setPathToMono(String pathToMono) { this.pathToMono = pathToMono; } @Override public void execute() throws BuildException { dealWithReferences(); validateConfiguration(); populateSettings(); Engine engine = null; try { engine = new Engine(Check.class.getClassLoader()); if (isUpdateOnly()) { log("Deprecated 'UpdateOnly' property set; please use the UpdateTask instead", Project.MSG_WARN); try { engine.doUpdates(); } catch (UpdateException ex) { if (this.isFailOnError()) { throw new BuildException(ex); } log(ex.getMessage(), Project.MSG_ERR); } } else { for (Resource resource : getPath()) { final FileProvider provider = resource.as(FileProvider.class); if (provider != null) { final File file = provider.getFile(); if (file != null && file.exists()) { engine.scan(file); } } } try { engine.analyzeDependencies(); } catch (ExceptionCollection ex) { if (this.isFailOnError()) { 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); if (this.failBuildOnCVSS <= 10) { checkForFailure(engine.getDependencies()); } if (this.showSummary) { showSummary(engine.getDependencies()); } } } catch (DatabaseException ex) { final String msg = "Unable to connect to the dependency-check database; analysis has stopped"; if (this.isFailOnError()) { throw new BuildException(msg, ex); } log(msg, ex, Project.MSG_ERR); } catch (ReportException ex) { final String msg = "Unable to generate the dependency-check report"; if (this.isFailOnError()) { throw new BuildException(msg, ex); } log(msg, ex, Project.MSG_ERR); } finally { Settings.cleanup(true); if (engine != null) { engine.cleanup(); } } } /** * Validate the configuration to ensure the parameters have been properly * configured/initialized. * * @throws BuildException if the task was not configured correctly. */ private void validateConfiguration() throws BuildException { if (getPath() == null) { throw new BuildException("No project dependencies have been defined to analyze."); } if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) { throw new BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11."); } } /** * 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. * * @throws BuildException thrown when an invalid setting is configured. */ @Override protected void populateSettings() throws BuildException { super.populateSettings(); Settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate); Settings.setStringIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); Settings.setStringIfNotEmpty(Settings.KEYS.HINTS_FILE, hintsFile); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_SWIFT_PACKAGE_MANAGER_ENABLED, swiftPackageManagerAnalyzerEnabled); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COCOAPODS_ENABLED, cocoapodsAnalyzerEnabled); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, bundleAuditAnalyzerEnabled); Settings.setStringIfNotNull(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, bundleAuditPath); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); Settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy); Settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); Settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); } /** * 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 BuildException thrown if a CVSS score is found that is higher * than the threshold set */ private void checkForFailure(List<Dependency> dependencies) throws BuildException { final StringBuilder ids = new StringBuilder(); for (Dependency d : dependencies) { for (Vulnerability v : d.getVulnerabilities()) { if (v.getCvssScore() >= failBuildOnCVSS) { if (ids.length() == 0) { ids.append(v.getName()); } else { ids.append(", ").append(v.getName()); } } } } if (ids.length() > 0) { final String msg = String.format("%n%nDependency-Check Failure:%n" + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater than '%.1f': %s%n" + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); throw new BuildException(msg); } } /** * Generates a warning message listing a summary of dependencies and their * associated CPE and CVE entries. * * @param dependencies a list of dependency objects */ private void showSummary(List<Dependency> dependencies) { final StringBuilder summary = new StringBuilder(); for (Dependency d : dependencies) { boolean firstEntry = true; final StringBuilder ids = new StringBuilder(); for (Vulnerability v : d.getVulnerabilities()) { if (firstEntry) { firstEntry = false; } else { ids.append(", "); } ids.append(v.getName()); } if (ids.length() > 0) { summary.append(d.getFileName()).append(" ("); firstEntry = true; for (Identifier id : d.getIdentifiers()) { if (firstEntry) { firstEntry = false; } else { summary.append(", "); } summary.append(id.getValue()); } summary.append(") : ").append(ids).append(NEW_LINE); } } if (summary.length() > 0) { final String msg = String.format("%n%n" + "One or more dependencies were identified with known vulnerabilities:%n%n%s" + "%n%nSee the dependency-check report for more details.%n%n", summary.toString()); log(msg, Project.MSG_WARN); } } /** * An enumeration of supported report formats: "ALL", "HTML", "XML", "CSV", "JSON", "VULN", * etc.. */ public static class ReportFormats extends EnumeratedAttribute { /** * Returns the list of values for the report format. * * @return the list of values for the report format */ @Override public String[] getValues() { int i = 0; final Format[] formats = Format.values(); final String[] values = new String[formats.length]; for (Format format : formats) { values[i++] = format.name(); } return values; } } }