Merge branch 'upmaster' into node-js-analyzer

Conflicts:
	dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java
	dependency-check-cli/src/site/markdown/arguments.md
	dependency-check-core/src/main/resources/META-INF/services/org.owasp.dependencycheck.analyzer.Analyzer
This commit is contained in:
Dale Visser
2015-08-25 13:03:12 -04:00
40 changed files with 805 additions and 193 deletions

View File

@@ -9,7 +9,7 @@ Current Releases
-------------
### Jenkins Plugin
For instructions on the use of the Jenkins plugin please see the [Jenkins dependency-check page](http://wiki.jenkins-ci.org/x/CwDgAQ).
For instructions on the use of the Jenkins plugin please see the [OWASP Dependency-Check Plugin page](https://wiki.jenkins-ci.org/display/JENKINS/OWASP+Dependency-Check+Plugin).
### Command Line
@@ -37,7 +37,7 @@ $ dependency-check --app Testing --out . --scan [path to jar files to be scanned
### Maven Plugin
More detailed instructions can be found on the [dependency-check-maven github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-maven/usage.html).
More detailed instructions can be found on the [dependency-check-maven github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-maven).
The plugin can be configured using the following:
```xml
@@ -66,7 +66,7 @@ The plugin can be configured using the following:
### Ant Task
For instructions on the use of the Ant Task, please see the [dependency-check-ant github page](http://jeremylong.github.io/DependencyCheck/dependency-check-ant/installation.html).
For instructions on the use of the Ant Task, please see the [dependency-check-ant github page](http://jeremylong.github.io/DependencyCheck/dependency-check-ant).
Development Usage
-------------

View File

@@ -20,7 +20,7 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.3.0</version>
<version>1.3.1-SNAPSHOT</version>
</parent>
<artifactId>dependency-check-ant</artifactId>

View File

@@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.3.0</version>
<version>1.3.1-SNAPSHOT</version>
</parent>
<artifactId>dependency-check-cli</artifactId>

View File

@@ -326,6 +326,7 @@ public class App {
Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !assemblyDisabled);
Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, !cli.isNodeJsDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, !cli.isRubyGemspecDisabled());
Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !centralDisabled);
Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !nexusDisabled);

View File

@@ -416,6 +416,8 @@ public final class CliParser {
.addOption(disablePythonDistributionAnalyzer)
.addOption(disableCmakeAnalyzer)
.addOption(disablePythonPackageAnalyzer)
.addOption(OptionBuilder.withLongOpt(ARGUMENT.DISABLE_RUBYGEMS)
.withDescription("Disable the Ruby Gemspec Analyzer.").create())
.addOption(disableAutoconfAnalyzer)
.addOption(disableOpenSSLAnalyzer)
.addOption(disableNuspecAnalyzer)
@@ -545,6 +547,15 @@ public final class CliParser {
return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG);
}
/**
* Returns whether the Ruby gemspec analyzer is disabled.
*
* @return true if the {@link ARGUMENT#DISABLE_RUBYGEMS} command line argument was specified; otherwise false
*/
public boolean isRubyGemspecDisabled() {
return (null != line) && line.hasOption(ARGUMENT.DISABLE_RUBYGEMS);
}
/**
* Returns true if the disableCmake command line argument was specified.
*
@@ -1088,6 +1099,10 @@ public final class CliParser {
* Disables the Python Package Analyzer.
*/
public static final String DISABLE_PY_PKG = "disablePyPkg";
/**
* Disables the Ruby Gemspec Analyzer.
*/
public static final String DISABLE_RUBYGEMS = "disableRubygems";
/**
* Disables the Autoconf Analyzer.
*/

View File

@@ -13,7 +13,7 @@ Short | Argument&nbsp;Name&nbsp;&nbsp; | Parameter | Description | Requir
\-f | \-\-format | \<format\> | The output format to write to (XML, HTML, VULN, ALL). The default is HTML. | Required
\-l | \-\-log | \<file\> | The file path to write verbose logging information. | Optional
\-n | \-\-noupdate | | Disables the automatic updating of the CPE data. | Optional
| \-\-suppression | \<file\> | The file path to the suppression XML file; used to suppress [false positives](../suppression.html). | Optional
| \-\-suppression | \<file\> | The file path to the suppression XML file; used to suppress [false positives](../general/suppression.html). | Optional
\-h | \-\-help | | Print the help message. | Optional
| \-\-advancedHelp | | Print the advanced help message. | Optional
\-v | \-\-version | | Print the version information. | Optional
@@ -30,7 +30,8 @@ Short | Argument&nbsp;Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Paramete
| \-\-updateonly | | If set only the update phase of dependency-check will be executed; no scan will be executed and no report will be generated. | &nbsp;
| \-\-disablePyDist | | Sets whether the Python Distribution Analyzer will be used. | false
| \-\-disablePyPkg | | Sets whether the Python Package Analyzer will be used. | false
| \-\-disableNodeJS | | Sets whehter the Node.js Package Analyzer will be used. | false
| \-\-disableNodeJS | | Sets whehter the Node.js Package Analyzer will be used. | false
| \-\-disableRubygems | | Sets whether the Ruby Gemspec Analyzer will be used. | false
| \-\-disableAutoconf | | Sets whether the Autoconf Analyzer will be used. | false
| \-\-disableOpenSSL | | Sets whether the OpenSSL Analyzer will be used. | false
| \-\-disableCmake | | Sets whether the Cmake Analyzer will be used. | false

View File

@@ -20,7 +20,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.3.0</version>
<version>1.3.1-SNAPSHOT</version>
</parent>
<artifactId>dependency-check-core</artifactId>
@@ -123,6 +123,11 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<goals>
<goal>test-jar</goal>
</goals>
<configuration>
<includes>
<include>**/*.class</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>

View File

@@ -173,10 +173,10 @@ public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
}
} else {
// copy, alter and set in case some other thread is iterating over
final List<Dependency> deps = new ArrayList<Dependency>(
final List<Dependency> dependencies = new ArrayList<Dependency>(
engine.getDependencies());
deps.remove(dependency);
engine.setDependencies(deps);
dependencies.remove(dependency);
engine.setDependencies(dependencies);
}
}
@@ -225,7 +225,7 @@ public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
contents = FileUtils.readFileToString(actualFile).trim();
} catch (IOException e) {
throw new AnalysisException(
"Problem occured while reading dependency file.", e);
"Problem occurred while reading dependency file.", e);
}
return contents;
}

View File

@@ -53,7 +53,7 @@ import org.owasp.dependencycheck.utils.UrlStringUtils;
public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
/**
* Name of egg metatdata files to analyze.
* Name of egg metadata files to analyze.
*/
private static final String PKG_INFO = "PKG-INFO";
@@ -269,10 +269,8 @@ public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
*
* @param dependency the dependency being analyzed
* @param file a reference to the manifest/properties file
* @throws AnalysisException thrown when there is an error
*/
private static void collectWheelMetadata(Dependency dependency, File file)
throws AnalysisException {
private static void collectWheelMetadata(Dependency dependency, File file) {
final InternetHeaders headers = getManifestProperties(file);
addPropertyToEvidence(headers, dependency.getVersionEvidence(),
"Version", Confidence.HIGHEST);
@@ -352,7 +350,7 @@ public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
}
/**
* Retrieves the next temporary destingation directory for extracting an archive.
* Retrieves the next temporary destination directory for extracting an archive.
*
* @return a directory
* @throws AnalysisException thrown if unable to create temporary directory

View File

@@ -28,13 +28,10 @@ import org.owasp.dependencycheck.dependency.EvidenceCollection;
import org.owasp.dependencycheck.utils.FileFilterBuilder;
import org.owasp.dependencycheck.utils.Settings;
import org.owasp.dependencycheck.utils.UrlStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
@@ -53,12 +50,6 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
private static final int REGEX_OPTIONS = Pattern.DOTALL
| Pattern.CASE_INSENSITIVE;
/**
* The logger.
*/
private static final Logger LOGGER = LoggerFactory
.getLogger(PythonPackageAnalyzer.class);
/**
* Filename extensions for files to be analyzed.
*/
@@ -173,7 +164,7 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
* Analyzes python packages and adds evidence to the dependency.
*
* @param dependency the dependency being analyzed
* @param engine the engine being used to perform the scan
* @param engine the engine being used to perform the scan
* @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency
*/
@Override
@@ -184,8 +175,8 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
final String parentName = parent.getName();
boolean found = false;
if (INIT_PY_FILTER.accept(file)) {
for (final File sourcefile : parent.listFiles(PY_FILTER)) {
found |= analyzeFileContents(dependency, sourcefile);
for (final File sourceFile : parent.listFiles(PY_FILTER)) {
found |= analyzeFileContents(dependency, sourceFile);
}
}
if (found) {
@@ -194,10 +185,10 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
"PackageName", parentName, Confidence.MEDIUM);
} else {
// copy, alter and set in case some other thread is iterating over
final List<Dependency> deps = new ArrayList<Dependency>(
final List<Dependency> dependencies = new ArrayList<Dependency>(
engine.getDependencies());
deps.remove(dependency);
engine.setDependencies(deps);
dependencies.remove(dependency);
engine.setDependencies(dependencies);
}
}
@@ -206,7 +197,7 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
* __summary__, __uri__, __url__, __home*page__, __author__, and their all caps equivalents.
*
* @param dependency the dependency being analyzed
* @param file the file name to analyze
* @param file the file name to analyze
* @return whether evidence was found
* @throws AnalysisException thrown if there is an unrecoverable error
*/
@@ -238,14 +229,10 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
.getVendorEvidence();
found |= gatherEvidence(AUTHOR_PATTERN, contents, source,
vendorEvidence, "SourceAuthor", Confidence.MEDIUM);
try {
found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence,
source, "URL", contents);
found |= gatherHomePageEvidence(HOMEPAGE_PATTERN,
vendorEvidence, source, "HomePage", contents);
} catch (MalformedURLException e) {
LOGGER.warn(e.getMessage());
}
found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence,
source, "URL", contents);
found |= gatherHomePageEvidence(HOMEPAGE_PATTERN,
vendorEvidence, source, "HomePage", contents);
}
return found;
}
@@ -254,15 +241,15 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
* Adds summary information to the dependency
*
* @param dependency the dependency being analyzed
* @param pattern the pattern used to perform analysis
* @param group the group from the pattern that indicates the data to use
* @param contents the data being analyzed
* @param source the source name to use when recording the evidence
* @param key the key name to use when recording the evidence
* @param pattern the pattern used to perform analysis
* @param group the group from the pattern that indicates the data to use
* @param contents the data being analyzed
* @param source the source name to use when recording the evidence
* @param key the key name to use when recording the evidence
* @return true if evidence was collected; otherwise false
*/
private boolean addSummaryInfo(Dependency dependency, Pattern pattern,
int group, String contents, String source, String key) {
int group, String contents, String source, String key) {
final Matcher matcher = pattern.matcher(contents);
final boolean found = matcher.find();
if (found) {
@@ -275,17 +262,16 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
/**
* Collects evidence from the home page URL.
*
* @param pattern the pattern to match
* @param pattern the pattern to match
* @param evidence the evidence collection to add the evidence to
* @param source the source of the evidence
* @param name the name of the evidence
* @param source the source of the evidence
* @param name the name of the evidence
* @param contents the home page URL
* @return true if evidence was collected; otherwise false
* @throws MalformedURLException thrown if the URL is malformed
*/
private boolean gatherHomePageEvidence(Pattern pattern,
EvidenceCollection evidence, String source, String name,
String contents) throws MalformedURLException {
EvidenceCollection evidence, String source, String name,
String contents) {
final Matcher matcher = pattern.matcher(contents);
boolean found = false;
if (matcher.find()) {
@@ -299,19 +285,19 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
}
/**
* Gather evidence from a Python source file usin the given string assignment regex pattern.
* Gather evidence from a Python source file using the given string assignment regex pattern.
*
* @param pattern to scan contents with
* @param contents of Python source file
* @param source for storing evidence
* @param evidence to store evidence in
* @param name of evidence
* @param pattern to scan contents with
* @param contents of Python source file
* @param source for storing evidence
* @param evidence to store evidence in
* @param name of evidence
* @param confidence in evidence
* @return whether evidence was found
*/
private boolean gatherEvidence(Pattern pattern, String contents,
String source, EvidenceCollection evidence, String name,
Confidence confidence) {
String source, EvidenceCollection evidence, String name,
Confidence confidence) {
final Matcher matcher = pattern.matcher(contents);
final boolean found = matcher.find();
if (found) {

View File

@@ -0,0 +1,160 @@
/*
* 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) 2015 Institute for Defense Analyses. All Rights Reserved.
*/
package org.owasp.dependencycheck.analyzer;
import org.apache.commons.io.FileUtils;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.dependency.Confidence;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.EvidenceCollection;
import org.owasp.dependencycheck.utils.FileFilterBuilder;
import org.owasp.dependencycheck.utils.Settings;
import java.io.FileFilter;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Used to analyze Ruby Gem specifications and collect information that can be used to determine the associated CPE.
* Regular expressions are used to parse the well-defined Ruby syntax that forms the specification.
*
* @author Dale Visser <dvisser@ida.org>
*/
public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
/**
* The name of the analyzer.
*/
private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer";
/**
* The phase that this analyzer is intended to run in.
*/
private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
private static final FileFilter FILTER =
FileFilterBuilder.newInstance().addExtensions("gemspec").addFilenames("Rakefile").build();
private static final String EMAIL = "email";
private static final String GEMSPEC = "gemspec";
/**
* @return a filter that accepts files named Rakefile or matching the glob pattern, *.gemspec
*/
@Override
protected FileFilter getFileFilter() {
return FILTER;
}
@Override
protected void initializeFileTypeAnalyzer() throws Exception {
// NO-OP
}
/**
* Returns the name of the analyzer.
*
* @return the name of the analyzer.
*/
@Override
public String getName() {
return ANALYZER_NAME;
}
/**
* Returns the phase that the analyzer is intended to run in.
*
* @return the phase that the analyzer is intended to run in.
*/
@Override
public AnalysisPhase getAnalysisPhase() {
return ANALYSIS_PHASE;
}
/**
* Returns the key used in the properties file to reference the analyzer's enabled property.
*
* @return the analyzer's enabled property setting key
*/
@Override
protected String getAnalyzerEnabledSettingKey() {
return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED;
}
/**
* The capture group #1 is the block variable.
*/
private static final Pattern GEMSPEC_BLOCK_INIT =
Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|");
@Override
protected void analyzeFileType(Dependency dependency, Engine engine)
throws AnalysisException {
String contents;
try {
contents = FileUtils.readFileToString(dependency.getActualFile());
} catch (IOException e) {
throw new AnalysisException(
"Problem occurred while reading dependency file.", e);
}
final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents);
if (matcher.find()) {
contents = contents.substring(matcher.end());
final String blockVariable = matcher.group(1);
final EvidenceCollection vendor = dependency.getVendorEvidence();
addStringEvidence(vendor, contents, blockVariable, "author", Confidence.HIGHEST);
addListEvidence(vendor, contents, blockVariable, "authors", Confidence.HIGHEST);
final String email = addStringEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM);
if (email.isEmpty()) {
addListEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM);
}
addStringEvidence(vendor, contents, blockVariable, "homepage", Confidence.MEDIUM);
final EvidenceCollection product = dependency.getProductEvidence();
final String name = addStringEvidence(product, contents, blockVariable, "name", Confidence.HIGHEST);
if (!name.isEmpty()) {
vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW);
}
addStringEvidence(product, contents, blockVariable, "summary", Confidence.LOW);
addStringEvidence(dependency.getVersionEvidence(), contents, blockVariable, "version", Confidence.HIGHEST);
}
}
private void addListEvidence(EvidenceCollection evidences, String contents,
String blockVariable, String field, Confidence confidence) {
final Matcher matcher = Pattern.compile(
String.format("\\s+?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, field)).matcher(contents);
if (matcher.find()) {
final String value = matcher.group(1).replaceAll("['\"]", " ").trim();
evidences.addEvidence(GEMSPEC, field, value, confidence);
}
}
private String addStringEvidence(EvidenceCollection evidences, String contents,
String blockVariable, String field, Confidence confidence) {
final Matcher matcher = Pattern.compile(
String.format("\\s+?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, field)).matcher(contents);
String value = "";
if (matcher.find()) {
value = matcher.group(2);
evidences.addEvidence(GEMSPEC, field, value, confidence);
}
return value;
}
}

View File

@@ -720,7 +720,7 @@ public class Dependency implements Serializable, Comparable<Dependency> {
&& ObjectUtils.equals(this.description, other.description)
&& ObjectUtils.equals(this.license, other.license)
&& ObjectUtils.equals(this.vulnerabilities, other.vulnerabilities)
&& ObjectUtils.equals(this.relatedDependencies, other.relatedDependencies)
//&& ObjectUtils.equals(this.relatedDependencies, other.relatedDependencies)
&& ObjectUtils.equals(this.projectReferences, other.projectReferences)
&& ObjectUtils.equals(this.availableVersions, other.availableVersions);
}
@@ -735,8 +735,9 @@ public class Dependency implements Serializable, Comparable<Dependency> {
int hash = MAGIC_HASH_INIT_VALUE;
for (Object field : new Object[]{this.actualFilePath, this.filePath, this.fileName, this.md5sum,
this.sha1sum, this.identifiers, this.vendorEvidence, this.productEvidence, this.versionEvidence,
this.description, this.license, this.vulnerabilities, this.relatedDependencies, this.projectReferences,
this.availableVersions}) {
this.description, this.license, this.vulnerabilities,
//this.relatedDependencies,
this.projectReferences, this.availableVersions}) {
hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(field);
}
return hash;

View File

@@ -17,4 +17,5 @@ org.owasp.dependencycheck.analyzer.PythonPackageAnalyzer
org.owasp.dependencycheck.analyzer.AutoconfAnalyzer
org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer
org.owasp.dependencycheck.analyzer.CMakeAnalyzer
org.owasp.dependencycheck.analyzer.NodePackageAnalyzer
org.owasp.dependencycheck.analyzer.NodePackageAnalyzer
org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer

View File

@@ -17,6 +17,7 @@
<cpe>cpe:/a:mod_security:mod_security</cpe>
<cpe>cpe:/a:springsource:spring_framework</cpe>
<cpe>cpe:/a:vmware:springsource_spring_framework</cpe>
<cpe>cpe:/a:pivotal:spring_framework</cpe>
</suppress>
<suppress base="true">
<notes><![CDATA[

View File

@@ -504,7 +504,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<div id="modal-background"></div>
<div id="modal-content">
<div>Press CTR-C to copy XML&nbsp;<a href="http://jeremylong.github.io/DependencyCheck/suppression.html" class="infolink" target="_blank" title="Help with suppressing false positives">[help]</a></div>
<textarea id="modal-text" cols="50" rows="10"></textarea><br/>
<textarea id="modal-text" cols="50" rows="10" readonly></textarea><br/>
<button id="modal-add-header" title="Add the parent XML nodes to create the complete XML file that can be used to suppress this finding" class="modal-button">Complete XML Doc</button><button id="modal-close" class="modal-button-right">Close</button>
</div>
<div class="wrapper">
@@ -591,6 +591,7 @@ arising out of or in connection with the use of this tool, the analysis performe
#else
$enc.html($id.value)
#end
#set($cpeSort=0)
#if ($cpeIdConf == "")
#set($cpeIdConf=$id.confidence)
#set($cpeSort=$id.confidence.ordinal())
@@ -602,11 +603,15 @@ arising out of or in connection with the use of this tool, the analysis performe
#end
#end
</td>
#if ($mavenlink=="")
<td data-sort-value="">
#else
<td data-sort-value="$enc.html($mavenlink.value)">#if( $mavenlink.url )
##yes, we are HTML Encoding the href. this is okay. We can't URL encode as we have to trust the analyzer here...
##yes, we are HTML Encoding the href. This is okay. We can't URL encode as we have to trust the analyzer here...
<a href="$enc.html($mavenlink.url)" target="_blank">$enc.html($mavenlink.value)</a>
#elseif ($mavenlink.value)
$enc.html($mavenlink.value)
#end
#end</td>
#set($cveImpact=-1)
#foreach($vuln in $dependency.getVulnerabilities())

View File

@@ -39,10 +39,10 @@ public class OpenSSLAnalyzerTest extends BaseTest {
/**
* The package analyzer to test.
*/
OpenSSLAnalyzer analyzer;
private OpenSSLAnalyzer analyzer;
/**
* Setup the PtyhonPackageAnalyzer.
* Setup the {@link OpenSSLAnalyzer}.
*
* @throws Exception if there is a problem
*/

View File

@@ -40,7 +40,7 @@ public class PythonDistributionAnalyzerTest extends BaseTest {
/**
* The analyzer to test.
*/
PythonDistributionAnalyzer analyzer;
private PythonDistributionAnalyzer analyzer;
/**
* Correctly setup the analyzer for testing.

View File

@@ -40,10 +40,10 @@ public class PythonPackageAnalyzerTest extends BaseTest {
/**
* The package analyzer to test.
*/
PythonPackageAnalyzer analyzer;
private PythonPackageAnalyzer analyzer;
/**
* Setup the PtyhonPackageAnalyzer.
* Setup the {@link PythonPackageAnalyzer}.
*
* @throws Exception if there is a problem
*/
@@ -85,14 +85,9 @@ public class PythonPackageAnalyzerTest extends BaseTest {
@Test
public void testAnalyzeSourceMetadata() throws AnalysisException {
eggtestAssertions(this,
"python/eggtest/__init__.py");
}
public void eggtestAssertions(Object context, final String resource) throws AnalysisException {
boolean found = false;
final Dependency result = new Dependency(BaseTest.getResourceAsFile(
context, resource));
this, "python/eggtest/__init__.py"));
analyzer.analyze(result, null);
assertTrue("Expected vendor evidence to contain \"example\".", result
.getVendorEvidence().toString().contains("example"));
@@ -104,4 +99,5 @@ public class PythonPackageAnalyzerTest extends BaseTest {
}
assertTrue("Version 0.0.1 not found in EggTest dependency.", found);
}
}

View File

@@ -0,0 +1,103 @@
/*
* 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) 2015 Institute for Defense Analyses. All Rights Reserved.
*/
package org.owasp.dependencycheck.analyzer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.owasp.dependencycheck.BaseTest;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.dependency.Dependency;
import java.io.File;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
/**
* Unit tests for {@link RubyGemspecAnalyzer}.
*
* @author Dale Visser <dvisser@ida.org>
*/
public class RubyGemspecAnalyzerTest extends BaseTest {
/**
* The analyzer to test.
*/
RubyGemspecAnalyzer analyzer;
/**
* Correctly setup the analyzer for testing.
*
* @throws Exception thrown if there is a problem
*/
@Before
public void setUp() throws Exception {
analyzer = new RubyGemspecAnalyzer();
analyzer.setFilesMatched(true);
analyzer.initialize();
}
/**
* Cleanup the analyzer's temp files, etc.
*
* @throws Exception thrown if there is a problem
*/
@After
public void tearDown() throws Exception {
analyzer.close();
analyzer = null;
}
/**
* Test of getName method, of class PythonDistributionAnalyzer.
*/
@Test
public void testGetName() {
assertThat(analyzer.getName(), is("Ruby Gemspec Analyzer"));
}
/**
* Test of supportsExtension method, of class PythonDistributionAnalyzer.
*/
@Test
public void testSupportsFiles() {
assertThat(analyzer.accept(new File("test.gemspec")), is(true));
assertThat(analyzer.accept(new File("Rakefile")), is(true));
}
/**
* Test of inspect method, of class PythonDistributionAnalyzer.
*
* @throws AnalysisException is thrown when an exception occurs.
*/
@Test
public void testAnalyzePackageJson() throws AnalysisException {
final Dependency result = new Dependency(BaseTest.getResourceAsFile(this,
"ruby/gems/specifications/rest-client-1.7.2.gemspec"));
analyzer.analyze(result, null);
final String vendorString = result.getVendorEvidence().toString();
assertThat(vendorString, containsString("REST Client Team"));
assertThat(vendorString, containsString("rest-client_project"));
assertThat(vendorString, containsString("rest.client@librelist.com"));
assertThat(vendorString, containsString("https://github.com/rest-client/rest-client"));
assertThat(result.getProductEvidence().toString(), containsString("rest-client"));
assertThat(result.getVersionEvidence().toString(), containsString("1.7.2"));
}
}

View File

@@ -0,0 +1,72 @@
# -*- encoding: utf-8 -*-
# stub: mime-types 2.6.1 ruby lib
Gem::Specification.new do |s|
s.name = "mime-types"
s.version = "2.6.1"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib"]
s.authors = ["Austin Ziegler"]
s.date = "2015-05-25"
s.description = "The mime-types library provides a library and registry for information about\nMIME content type definitions. It can be used to determine defined filename\nextensions for MIME types, or to use filename extensions to look up the likely\nMIME type definitions.\n\nMIME content types are used in MIME-compliant communications, as in e-mail or\nHTTP traffic, to indicate the type of content which is transmitted. The\nmime-types library provides the ability for detailed information about MIME\nentities (provided as an enumerable collection of MIME::Type objects) to be\ndetermined and used. There are many types defined by RFCs and vendors, so the\nlist is long but by definition incomplete; don't hesitate to add additional\ntype definitions. MIME type definitions found in mime-types are from RFCs, W3C\nrecommendations, the {IANA Media Types\nregistry}[https://www.iana.org/assignments/media-types/media-types.xhtml], and\nuser contributions. It conforms to RFCs 2045 and 2231.\n\nThis is release 2.6 with two new experimental features. The first new feature\nis a new default registry storage format that greatly reduces the initial\nmemory use of the mime-types library. This feature is enabled by requiring\n+mime/types/columnar+ instead of +mime/types+ with a small performance cost and\nno change in *total* memory use if certain methods are called (see {Columnar\nStore}[#columnar-store] for more details). The second new feature is a logger\ninterface that conforms to the expectations of an ActiveSupport::Logger so that\nwarnings can be written to an application's log rather than the default\nlocation for +warn+. This interface may be used for other logging purposes in\nthe future.\n\nmime-types 2.6 is the last planned version of mime-types 2.x, so deprecation\nwarnings are no longer cached but provided every time the method is called.\nmime-types 2.6 supports Ruby 1.9.2 or later."
s.email = ["halostatue@gmail.com"]
s.extra_rdoc_files = ["Contributing.rdoc", "History-Types.rdoc", "History.rdoc", "Licence.rdoc", "Manifest.txt", "README.rdoc", "docs/COPYING.txt", "docs/artistic.txt"]
s.files = ["Contributing.rdoc", "History-Types.rdoc", "History.rdoc", "Licence.rdoc", "Manifest.txt", "README.rdoc", "docs/COPYING.txt", "docs/artistic.txt"]
s.homepage = "https://github.com/mime-types/ruby-mime-types/"
s.licenses = ["MIT", "Artistic 2.0", "GPL-2"]
s.rdoc_options = ["--main", "README.rdoc"]
s.required_ruby_version = Gem::Requirement.new(">= 1.9.2")
s.rubygems_version = "2.2.2"
s.summary = "The mime-types library provides a library and registry for information about MIME content type definitions"
s.installed_by_version = "2.2.2" if s.respond_to? :installed_by_version
if s.respond_to? :specification_version then
s.specification_version = 4
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_development_dependency(%q<minitest>, ["~> 5.6"])
s.add_development_dependency(%q<rdoc>, ["~> 4.0"])
s.add_development_dependency(%q<hoe-doofus>, ["~> 1.0"])
s.add_development_dependency(%q<hoe-gemspec2>, ["~> 1.1"])
s.add_development_dependency(%q<hoe-git>, ["~> 1.6"])
s.add_development_dependency(%q<hoe-rubygems>, ["~> 1.0"])
s.add_development_dependency(%q<hoe-travis>, ["~> 1.2"])
s.add_development_dependency(%q<minitest-autotest>, ["~> 1.0"])
s.add_development_dependency(%q<minitest-focus>, ["~> 1.0"])
s.add_development_dependency(%q<rake>, ["~> 10.0"])
s.add_development_dependency(%q<simplecov>, ["~> 0.7"])
s.add_development_dependency(%q<coveralls>, ["~> 0.8"])
s.add_development_dependency(%q<hoe>, ["~> 3.13"])
else
s.add_dependency(%q<minitest>, ["~> 5.6"])
s.add_dependency(%q<rdoc>, ["~> 4.0"])
s.add_dependency(%q<hoe-doofus>, ["~> 1.0"])
s.add_dependency(%q<hoe-gemspec2>, ["~> 1.1"])
s.add_dependency(%q<hoe-git>, ["~> 1.6"])
s.add_dependency(%q<hoe-rubygems>, ["~> 1.0"])
s.add_dependency(%q<hoe-travis>, ["~> 1.2"])
s.add_dependency(%q<minitest-autotest>, ["~> 1.0"])
s.add_dependency(%q<minitest-focus>, ["~> 1.0"])
s.add_dependency(%q<rake>, ["~> 10.0"])
s.add_dependency(%q<simplecov>, ["~> 0.7"])
s.add_dependency(%q<coveralls>, ["~> 0.8"])
s.add_dependency(%q<hoe>, ["~> 3.13"])
end
else
s.add_dependency(%q<minitest>, ["~> 5.6"])
s.add_dependency(%q<rdoc>, ["~> 4.0"])
s.add_dependency(%q<hoe-doofus>, ["~> 1.0"])
s.add_dependency(%q<hoe-gemspec2>, ["~> 1.1"])
s.add_dependency(%q<hoe-git>, ["~> 1.6"])
s.add_dependency(%q<hoe-rubygems>, ["~> 1.0"])
s.add_dependency(%q<hoe-travis>, ["~> 1.2"])
s.add_dependency(%q<minitest-autotest>, ["~> 1.0"])
s.add_dependency(%q<minitest-focus>, ["~> 1.0"])
s.add_dependency(%q<rake>, ["~> 10.0"])
s.add_dependency(%q<simplecov>, ["~> 0.7"])
s.add_dependency(%q<coveralls>, ["~> 0.8"])
s.add_dependency(%q<hoe>, ["~> 3.13"])
end
end

View File

@@ -0,0 +1,32 @@
# -*- encoding: utf-8 -*-
# stub: netrc 0.10.3 ruby lib
Gem::Specification.new do |s|
s.name = "netrc"
s.version = "0.10.3"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib"]
s.authors = ["Keith Rarick", "geemus (Wesley Beary)"]
s.date = "2015-02-24"
s.description = "This library can read and update netrc files, preserving formatting including comments and whitespace."
s.email = "geemus@gmail.com"
s.homepage = "https://github.com/geemus/netrc"
s.licenses = ["MIT"]
s.rubygems_version = "2.2.2"
s.summary = "Library to read and write netrc files."
s.installed_by_version = "2.2.2" if s.respond_to? :installed_by_version
if s.respond_to? :specification_version then
s.specification_version = 4
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_development_dependency(%q<turn>, [">= 0"])
else
s.add_dependency(%q<turn>, [">= 0"])
end
else
s.add_dependency(%q<turn>, [">= 0"])
end
end

View File

@@ -0,0 +1,54 @@
# -*- encoding: utf-8 -*-
# stub: rest-client 1.7.2 ruby lib
Gem::Specification.new do |s|
s.name = "rest-client"
s.version = "1.7.2"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib"]
s.authors = ["REST Client Team"]
s.date = "2014-07-14"
s.description = "A simple HTTP and REST client for Ruby, inspired by the Sinatra microframework style of specifying actions: get, put, post, delete."
s.email = "rest.client@librelist.com"
s.executables = ["restclient"]
s.extra_rdoc_files = ["README.rdoc", "history.md"]
s.files = ["README.rdoc", "bin/restclient", "history.md"]
s.homepage = "https://github.com/rest-client/rest-client"
s.licenses = ["MIT"]
s.required_ruby_version = Gem::Requirement.new(">= 1.9.2")
s.rubygems_version = "2.2.2"
s.summary = "Simple HTTP and REST client for Ruby, inspired by microframework syntax for specifying actions."
s.installed_by_version = "2.2.2" if s.respond_to? :installed_by_version
if s.respond_to? :specification_version then
s.specification_version = 3
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_development_dependency(%q<webmock>, ["~> 1.4"])
s.add_development_dependency(%q<rspec>, ["~> 2.4"])
s.add_development_dependency(%q<pry>, [">= 0"])
s.add_development_dependency(%q<pry-doc>, [">= 0"])
s.add_development_dependency(%q<rdoc>, ["< 5.0", ">= 2.4.2"])
s.add_runtime_dependency(%q<mime-types>, ["< 3.0", ">= 1.16"])
s.add_runtime_dependency(%q<netrc>, ["~> 0.7"])
else
s.add_dependency(%q<webmock>, ["~> 1.4"])
s.add_dependency(%q<rspec>, ["~> 2.4"])
s.add_dependency(%q<pry>, [">= 0"])
s.add_dependency(%q<pry-doc>, [">= 0"])
s.add_dependency(%q<rdoc>, ["< 5.0", ">= 2.4.2"])
s.add_dependency(%q<mime-types>, ["< 3.0", ">= 1.16"])
s.add_dependency(%q<netrc>, ["~> 0.7"])
end
else
s.add_dependency(%q<webmock>, ["~> 1.4"])
s.add_dependency(%q<rspec>, ["~> 2.4"])
s.add_dependency(%q<pry>, [">= 0"])
s.add_dependency(%q<pry-doc>, [">= 0"])
s.add_dependency(%q<rdoc>, ["< 5.0", ">= 2.4.2"])
s.add_dependency(%q<mime-types>, ["< 3.0", ">= 1.16"])
s.add_dependency(%q<netrc>, ["~> 0.7"])
end
end

View File

@@ -1,5 +1,6 @@
.idea/
.gradle
gradle/
*.iml
*.ipr

View File

@@ -7,6 +7,8 @@ This is a DependencyCheck gradle plugin designed for project which use Gradle as
Dependency-Check is a utility that attempts to detect publicly disclosed vulnerabilities contained within project dependencies. It does this by determining if there is a Common Platform Enumeration (CPE) identifier for a given dependency. If found, it will generate a report linking to the associated CVE entries.
Current latest version is `0.0.6`
=========
## Usage
@@ -15,7 +17,7 @@ Dependency-Check is a utility that attempts to detect publicly disclosed vulnera
Please refer to either one of the solution
#### Solution 1Install from Maven Central
#### Solution 1Install from Maven Central (Recommended)
```groovy
buildscript {
@@ -23,7 +25,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.thoughtworks.tools:dependency-check:0.0.5'
classpath 'com.thoughtworks.tools:dependency-check:0.0.6'
}
}
```
@@ -38,7 +40,7 @@ apply plugin: 'dependency.check'
```groovy
plugins {
id "dependency.check" version "0.0.5"
id "dependency.check" version "0.0.6"
}
```
@@ -52,11 +54,11 @@ buildscript {
}
}
dependencies {
classpath "gradle.plugin.com.tools.security:dependency-check:0.0.5"
classpath "gradle.plugin.com.tools.security:dependency-check:0.0.6"
}
}
apply plugin: "dependency.check"
apply plugin: "dependency-check"
```
#### Solution 3Install from Bintray
@@ -73,7 +75,7 @@ buildscript {
}
dependencies {
classpath(
'com.tools.security:dependency-check:0.0.5'
'com.tools.security:dependency-check:0.0.6'
)
}
}
@@ -115,6 +117,19 @@ dependencyCheck {
}
```
In addition, if the proxy only allow HTTP `GET` or `POST` methods, you will find that the update process will always fail,
the root cause is that every time you run `dependencyCheck` task, it will try to query the latest timestamp to determine whether need to perform an update action,
and for performance reason the HTTP method it uses by default is `HEAD`, which probably is disabled or not supported by the proxy. To avoid this problem, you can simply change the HTTP method by below configuration:
```groovy
dependencyCheck {
proxyServer = "127.0.0.1" // required, the server name or IP address of the proxy
proxyPort = 3128 // required, the port number of the proxy
quickQueryTimestamp = false // when set to false, it means use HTTP GET method to query timestamp. (default value is true)
}
```
### What if my project includes multiple sub-project? How can I use this plugin for each of them including the root project?
Try put 'apply plugin: "dependency-check"' inside the 'allprojects' or 'subprojects' if you'd like to check all sub-projects only, see below:
@@ -127,7 +142,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath "gradle.plugin.com.tools.security:dependency-check:0.0.5"
classpath "gradle.plugin.com.tools.security:dependency-check:0.0.6"
}
}
@@ -144,7 +159,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath "gradle.plugin.com.tools.security:dependency-check:0.0.5"
classpath "gradle.plugin.com.tools.security:dependency-check:0.0.6"
}
}

View File

@@ -46,23 +46,15 @@ dependencies {
compile(
localGroovy(),
gradleApi(),
'org.owasp:dependency-check-core:1.2.11',
'org.owasp:dependency-check-utils:1.2.11'
'org.owasp:dependency-check-core:1.3.0',
'org.owasp:dependency-check-utils:1.3.0'
)
testCompile ('com.netflix.nebula:nebula-test:2.2.+'){
testCompile ('com.netflix.nebula:nebula-test:2.2.2'){
exclude group: 'org.codehaus.groovy'
}
}
group = 'com.thoughtworks.tools'
version = '0.0.5'
apply from: 'conf/publish/local.gradle'
//apply from: 'conf/publish/maven.gradle'
apply from: 'conf/publish/gradlePluginsPortal.gradle'
//apply from: 'conf/publish/bintray.gradle' // according to the documentation of plugindev, this line has to be placed and the very end of the build file
sourceSets {
integTest {
groovy.srcDir file('src/integTest/groovy')
@@ -78,4 +70,14 @@ task integTest(type: Test) {
classpath = sourceSets.integTest.runtimeClasspath
reports.html.destination = file("$buildDir/reports/integ")
jvmArgs '-XX:MaxPermSize=256m'
}
}
group = 'com.thoughtworks.tools'
version = '0.0.6'
targetCompatibility = 1.7
apply from: 'conf/publish/local.gradle'
//apply from: 'conf/publish/maven.gradle'
apply from: 'conf/publish/gradlePluginsPortal.gradle'
//apply from: 'conf/publish/bintray.gradle' // according to the documentation of plugindev, this line has to be placed and the very end of the build file

View File

@@ -66,6 +66,11 @@ task javadocJar(type: Jar) {
from javadoc
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
artifacts {
archives javadocJar, sourcesJar
}

View File

@@ -22,11 +22,11 @@ Copyright (c) 2015 Wei Ma. All Rights Reserved.
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.3.0</version>
<version>1.3.1-SNAPSHOT</version>
</parent>
<artifactId>dependency-check-gradle</artifactId>
<version>0.0.5</version>
<version>0.0.6</version>
<!-- we must use gradle to build this, as such the packaging is pom -->
<packaging>pom</packaging>

View File

@@ -18,17 +18,19 @@
package com.tools.security.extension
class DependencyCheckConfigurationExtension {
class DependencyCheckExtension {
String proxyServer
Integer proxyPort
String proxyUsername = ""
String proxyPassword = ""
String proxyUsername
String proxyPassword
String cveUrl12Modified = "https://nvd.nist.gov/download/nvdcve-Modified.xml.gz"
String cveUrl20Modified = "https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-Modified.xml.gz"
Integer cveStartYear = 2002
String cveUrl12Base = "https://nvd.nist.gov/download/nvdcve-%d.xml.gz"
String cveUrl20Base = "https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml.gz"
String cveUrl20Modified
String cveUrl12Modified
Integer cveStartYear
String cveUrl20Base
String cveUrl12Base
String outputDirectory = "./reports"
Boolean quickQueryTimestamp;
}

View File

@@ -18,13 +18,14 @@
package com.tools.security.plugin
import com.tools.security.extension.DependencyCheckConfigurationExtension
import com.tools.security.extension.DependencyCheckExtension
import com.tools.security.tasks.DependencyCheckTask
import org.gradle.api.Plugin
import org.gradle.api.Project
class DependencyCheckGradlePlugin implements Plugin<Project> {
static final String EXTENSION_NAME = 'dependencyCheck'
private static final String EXTENSION_NAME = 'dependencyCheck'
private static final String TASK_NAME = 'dependencyCheck'
@Override
void apply(Project project) {
@@ -33,22 +34,10 @@ class DependencyCheckGradlePlugin implements Plugin<Project> {
}
def initializeConfigurations(Project project) {
project.extensions.create(EXTENSION_NAME, DependencyCheckConfigurationExtension)
project.extensions.create(EXTENSION_NAME, DependencyCheckExtension)
}
def registerTasks(Project project) {
project.task('dependencyCheck', type: DependencyCheckTask) {
def extension = project.extensions.findByName(EXTENSION_NAME)
conventionMapping.proxyServer = { extension.proxyServer }
conventionMapping.proxyPort = { extension.proxyPort }
conventionMapping.proxyUsername = { extension.proxyUsername }
conventionMapping.proxyPassword = { extension.proxyPassword }
conventionMapping.cveUrl12Modified = { extension.cveUrl12Modified }
conventionMapping.cveUrl20Modified = { extension.cveUrl20Modified }
conventionMapping.cveStartYear = { extension.cveStartYear }
conventionMapping.cveUrl12Base = { extension.cveUrl12Base }
conventionMapping.cveUrl20Base = { extension.cveUrl20Base }
conventionMapping.outputDirectory = { extension.outputDirectory }
}
project.task(TASK_NAME, type: DependencyCheckTask)
}
}

View File

@@ -28,24 +28,23 @@ import org.owasp.dependencycheck.dependency.Dependency
import org.owasp.dependencycheck.reporting.ReportGenerator
import org.owasp.dependencycheck.utils.Settings
import static org.owasp.dependencycheck.utils.Settings.KEYS.CVE_MODIFIED_12_URL
import static org.owasp.dependencycheck.utils.Settings.KEYS.CVE_MODIFIED_20_URL
import static org.owasp.dependencycheck.utils.Settings.KEYS.CVE_SCHEMA_1_2
import static org.owasp.dependencycheck.utils.Settings.KEYS.CVE_SCHEMA_2_0
import static org.owasp.dependencycheck.utils.Settings.KEYS.CVE_START_YEAR
import static org.owasp.dependencycheck.utils.Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP
import static org.owasp.dependencycheck.utils.Settings.KEYS.PROXY_PASSWORD
import static org.owasp.dependencycheck.utils.Settings.KEYS.PROXY_PORT
import static org.owasp.dependencycheck.utils.Settings.KEYS.PROXY_SERVER
import static org.owasp.dependencycheck.utils.Settings.KEYS.PROXY_USERNAME
import static org.owasp.dependencycheck.utils.Settings.setBoolean
import static org.owasp.dependencycheck.utils.Settings.setString
class DependencyCheckTask extends DefaultTask {
def currentProjectName = project.getName()
String proxyServer
Integer proxyPort
String proxyUsername = ""
String proxyPassword = ""
String cveUrl12Modified = "https://nvd.nist.gov/download/nvdcve-Modified.xml.gz"
String cveUrl20Modified = "https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-Modified.xml.gz"
Integer cveStartYear = 2002
String cveUrl12Base = "https://nvd.nist.gov/download/nvdcve-%d.xml.gz"
String cveUrl20Base = "https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml.gz"
String outputDirectory = "./reports"
def config = project.dependencyCheck
DependencyCheckTask() {
group = 'Dependency Check'
@@ -73,6 +72,7 @@ class DependencyCheckTask extends DefaultTask {
Settings.initialize()
overrideProxySetting()
overrideCveUrlSetting()
overrideDownloaderSetting()
}
def cleanup(engine) {
@@ -107,22 +107,22 @@ class DependencyCheckTask extends DefaultTask {
}
def generateReportDirectory(String currentProjectName) {
"${getOutputDirectory()}/${currentProjectName}"
"${config.outputDirectory}/${currentProjectName}"
}
def overrideProxySetting() {
if (isProxySettingExist()) {
logger.lifecycle("Using proxy ${getProxyServer()}:${getProxyPort()}")
logger.lifecycle("Using proxy ${config.proxyServer}:${config.proxyPort}")
setString(Settings.KEYS.PROXY_SERVER, getProxyServer())
setString(Settings.KEYS.PROXY_PORT, "${getProxyPort()}")
setString(Settings.KEYS.PROXY_USERNAME, getProxyUsername())
setString(Settings.KEYS.PROXY_PASSWORD, getProxyPassword())
overrideStringBasedSettingWhenProvided(PROXY_SERVER, config.proxyServer)
overrideStringBasedSettingWhenProvided(PROXY_PORT, "${config.proxyPort}")
overrideStringBasedSettingWhenProvided(PROXY_USERNAME, config.proxyUsername)
overrideStringBasedSettingWhenProvided(PROXY_PASSWORD, config.proxyPassword)
}
}
def isProxySettingExist() {
getProxyServer() != null && getProxyPort() != null
config.proxyServer != null && config.proxyPort != null
}
def getAllDependencies(project) {
@@ -134,10 +134,35 @@ class DependencyCheckTask extends DefaultTask {
}
def overrideCveUrlSetting() {
setString(Settings.KEYS.CVE_MODIFIED_20_URL, getCveUrl20Modified())
setString(Settings.KEYS.CVE_MODIFIED_12_URL, getCveUrl12Modified())
setString(Settings.KEYS.CVE_START_YEAR, "${getCveStartYear()}")
setString(Settings.KEYS.CVE_SCHEMA_2_0, getCveUrl20Base())
setString(Settings.KEYS.CVE_SCHEMA_1_2, getCveUrl12Base())
overrideStringBasedSettingWhenProvided(CVE_MODIFIED_20_URL, config.cveUrl20Modified)
overrideStringBasedSettingWhenProvided(CVE_MODIFIED_12_URL, config.cveUrl12Modified)
overrideIntegerBasedSettingWhenProvided(CVE_START_YEAR, config.cveStartYear)
overrideStringBasedSettingWhenProvided(CVE_SCHEMA_2_0, config.cveUrl20Base)
overrideStringBasedSettingWhenProvided(CVE_SCHEMA_1_2, config.cveUrl12Base)
}
def overrideDownloaderSetting() {
overrideBooleanBasedSettingWhenProvided(DOWNLOADER_QUICK_QUERY_TIMESTAMP, config.quickQueryTimestamp)
}
private overrideStringBasedSettingWhenProvided(String key, String providedValue) {
if (providedValue != null) {
logger.lifecycle("Setting [${key}] overrided with value [${providedValue}]")
setString(key, providedValue)
}
}
private overrideIntegerBasedSettingWhenProvided(String key, Integer providedValue) {
if (providedValue != null) {
logger.lifecycle("Setting [${key}] overrided with value [${providedValue}]")
setString(key, "${providedValue}")
}
}
private overrideBooleanBasedSettingWhenProvided(String key, Boolean providedValue) {
if (providedValue != null) {
logger.lifecycle("Setting [${key}] overrided with value [${providedValue}]")
setBoolean(key, providedValue)
}
}
}

View File

@@ -48,16 +48,17 @@ class DependencyCheckGradlePluginSpec extends PluginProjectSpec {
expect:
task.group == 'Dependency Check'
task.description == 'Produce dependency security report.'
task.proxyServer == null
task.proxyPort == null
task.proxyUsername == ''
task.proxyPassword == ''
task.cveUrl12Modified == 'https://nvd.nist.gov/download/nvdcve-Modified.xml.gz'
task.cveUrl20Modified == 'https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-Modified.xml.gz'
task.cveStartYear == 2002
task.cveUrl12Base == 'https://nvd.nist.gov/download/nvdcve-%d.xml.gz'
task.cveUrl20Base == 'https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml.gz'
task.outputDirectory == './reports'
project.dependencyCheck.proxyServer == null
project.dependencyCheck.proxyPort == null
project.dependencyCheck.proxyUsername == null
project.dependencyCheck.proxyPassword == null
project.dependencyCheck.cveUrl12Modified == null
project.dependencyCheck.cveUrl20Modified == null
project.dependencyCheck.cveStartYear == null
project.dependencyCheck.cveUrl12Base == null
project.dependencyCheck.cveUrl20Base == null
project.dependencyCheck.outputDirectory == './reports'
project.dependencyCheck.quickQueryTimestamp == null
}
def 'tasks use correct values when extension is used'() {
@@ -73,19 +74,20 @@ class DependencyCheckGradlePluginSpec extends PluginProjectSpec {
cveUrl12Base = 'cveUrl12Base'
cveUrl20Base = 'cveUrl20Base'
outputDirectory = 'outputDirectory'
quickQueryTimestamp = false
}
then:
Task task = project.tasks.findByName( 'dependencyCheck' )
task.proxyServer == '127.0.0.1'
task.proxyPort == 3128
task.proxyUsername == 'proxyUsername'
task.proxyPassword == 'proxyPassword'
task.cveUrl12Modified == 'cveUrl12Modified'
task.cveUrl20Modified == 'cveUrl20Modified'
task.cveStartYear == 2002
task.cveUrl12Base == 'cveUrl12Base'
task.cveUrl20Base == 'cveUrl20Base'
task.outputDirectory == 'outputDirectory'
project.dependencyCheck.proxyServer == '127.0.0.1'
project.dependencyCheck.proxyPort == 3128
project.dependencyCheck.proxyUsername == 'proxyUsername'
project.dependencyCheck.proxyPassword == 'proxyPassword'
project.dependencyCheck.cveUrl12Modified == 'cveUrl12Modified'
project.dependencyCheck.cveUrl20Modified == 'cveUrl20Modified'
project.dependencyCheck.cveStartYear == 2002
project.dependencyCheck.cveUrl12Base == 'cveUrl12Base'
project.dependencyCheck.cveUrl20Base == 'cveUrl20Base'
project.dependencyCheck.outputDirectory == 'outputDirectory'
project.dependencyCheck.quickQueryTimestamp == false
}
}

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.3.0</version>
<version>1.3.1-SNAPSHOT</version>
</parent>
<artifactId>dependency-check-jenkins</artifactId>
<name>Dependency-Check Jenkins Plugin</name>

View File

@@ -22,7 +22,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.3.0</version>
<version>1.3.1-SNAPSHOT</version>
</parent>
<artifactId>dependency-check-maven</artifactId>

View File

@@ -18,7 +18,7 @@ autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is ena
outputDirectory | The location to write the report(s). Note, this is not used if generating the report as part of a `mvn site` build | 'target'
failBuildOnCVSS | Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which means since the CVSS scores are 0-10, by default the build will never fail. | 11
format | The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the Site plugin unless the externalReport is set to true. | HTML
suppressionFile | The file path to the XML suppression file \- used to suppress [false positives](../suppression.html) | &nbsp;
suppressionFile | The file path to the XML suppression file \- used to suppress [false positives](../general/suppression.html) | &nbsp;
skipTestScope | Should be skip analysis for artifacts with Test Scope | true
skipProvidedScope | Should be skip analysis for artifacts with Provided Scope | false
skipRuntimeScope | Should be skip analysis for artifacts with Runtime Scope | false

View File

@@ -21,7 +21,7 @@ Copyright (c) 2014 - Jeremy Long. All Rights Reserved.
<parent>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.3.0</version>
<version>1.3.1-SNAPSHOT</version>
</parent>
<artifactId>dependency-check-utils</artifactId>

View File

@@ -31,6 +31,7 @@ import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.Properties;
import java.util.logging.Level;
/**
* A simple settings container that wraps the dependencycheck.properties file.
@@ -193,6 +194,10 @@ public final class Settings {
* The properties key for whether the Python Package analyzer is enabled.
*/
public static final String ANALYZER_PYTHON_PACKAGE_ENABLED = "analyzer.python.package.enabled";
/**
* The properties key for whether the Ruby Gemspec Analyzer is enabled.
*/
public static final String ANALYZER_RUBY_GEMSPEC_ENABLED = "analyzer.ruby.gemspec.enabled";
/**
* The properties key for whether the Autoconf analyzer is enabled.
*/
@@ -368,6 +373,14 @@ public final class Settings {
public static void cleanup(boolean deleteTemporary) {
if (deleteTemporary && tempDirectory != null && tempDirectory.exists()) {
FileUtils.delete(tempDirectory);
if (tempDirectory.exists()) {
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
//ignore
}
FileUtils.delete(tempDirectory);
}
}
try {
localSettings.remove();

View File

@@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long
<groupId>org.owasp</groupId>
<artifactId>dependency-check-parent</artifactId>
<version>1.3.0</version>
<version>1.3.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>

View File

@@ -3,12 +3,14 @@ File Type Analyzers
OWASP dependency-check contains several file type analyzers that are used
to extract identification information from the files analyzed.
- [Archive Analyzer](./archive-analyzer.html)
- [Assembly Analyzer](./assembly-analyzer.html)
- [Autoconf Analyzer](./autoconf-analyzer.html)
- [Central Analyzer](./central-analyzer.html)
- [Jar Analyzer](./jar-analyzer.html)
- [Nexus Analyzer](./nexus-analyzer.html)
- [Nuspec Analyzer](./nuspec-analyzer.html)
- [OpenSSL Analyzer](./openssl-analyzer.html)
- [Python Analyzer](./python-analyzer.html)
| Analyzer | File Types Scanned | Analysis Method |
| -------- | ------------------ | --------------- |
| [Archive Analyzer](./archive-analyzer.html) | Zip archive format (\*.zip, \*.ear, \*.war, \*.jar, \*.sar, \*.apk, \*.nupkg); Tape Archive Format (\*.tar); Gzip format (\*.gz, \*.tgz); Bzip2 format (\*.bz2, \*.tbz2) | Extracts archive contents, then scans contents with all available analyzers. |
| [Assembly Analyzer](./assembly-analyzer.html) | .NET Assemblies (\*.exe, \*.dll) | Uses [GrokAssembly.exe](https://github.com/colezlaw/GrokAssembly), which requires .NET Framework or Mono runtime to be installed. |
| [Autoconf Analyzer](./autoconf-analyzer.html) | Autoconf project configuration files (configure, configure.in, configure.ac) | Regex scan for AC_INIT metadata, including in generated configuration script. |
| [Central Analyzer](./central-analyzer.html) | Java archive files (\*.jar) | Searches Maven Central or a configured Nexus repository for the file's SHA1 hash. |
| [Jar Analyzer](./jar-analyzer.html) | Java archive files (\*.jar); Web application archive (\*.war) | Examines archive manifest metadata, and Maven Project Object Model files (pom.xml). |
| [Nexus Analyzer](./nexus-analyzer.html) | Java archive files (\*.jar) | Searches Sonatype or a configured Nexus repository for the file's SHA1 hash. In most cases, superceded by Central Analyzer. |
| [Nuspec Analyzer](./nuspec-analyzer.html) | Nuget package specification file (\*.nuspec) | Uses XPath to parse specification XML. |
| [OpenSSL Analyzer](./openssl-analyzer.html) | OpenSSL Version Source Header File (opensslv.h) | Regex parse of the OPENSSL_VERSION_NUMBER macro definition. |
| [Python Analyzer](./python-analyzer.html) | Python source files (\*.py); Package metadata files (PKG-INFO, METADATA); Package Distribution Files (\*.whl, \*.egg, \*.zip) | Regex scan of Python source files for setuptools metadata; Parse RFC822 header format for metadata in all other artifacts. |

View File

@@ -0,0 +1,122 @@
How to Mount ISO Files for Scanning
===================================
Dependency-Check can be used as one of your tools for vetting software
distributed via an [ISO image](https://en.wikipedia.org/wiki/ISO_image). (See
[File Type Analyzers](../analyzers/) for a list of what types of artifacts
Dependency-Check is capable of scanning.) These disk image files are not a standard archive format, however. Tools must be used that can interpret the contained file system. As will be shown below, Linux, Mac OS X, and recent versions of Windows can be used to mount the image's file system, which can
then be scanned by Dependency-Check.
ISO images are named for the fact that they nearly always contain one of a
pair of international file system standards published by
[ISO](http://www.iso.org/): [ISO 9660](https://en.wikipedia.org/wiki/ISO_9660)
and ISO/IEC 13346, a.k.a. [UDF](https://en.wikipedia.org/wiki/Universal_Disk_Format). Other types of disk images (e.g.,
[VHD](https://en.wikipedia.org/wiki/VHD_%28file_format%29)) are outside the
scope of this article, though the ideas presented here may likely be
succesfully applied.
Linux
-----
Assume you've downloaded an ISO image called `foo.iso`, and you want to mount
it at /mnt/foo. (Why /mnt? See the
[Filesystem Hierarchy Standard](http://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s12.html).)
First make sure that the mount point exists using `mkdir /mnt/foo`. Then, the
[mount](http://linux.die.net/man/8/mount) command *must be run with root
privileges*. On Debian and Ubuntu Linux, this is accomplished by prefacing the
command with `sudo`.
```sh
$ sudo mount -o loop foo.iso /mnt/foo
```
Next, you can use Dependency-Check's [command line tool](dependency-check-cli/)
to scan the mount point. When you are finished, run the
[umount](http://linux.die.net/man/8/umount) command with root privileges:
```sh
$ sudo umount -d /mnt/foo
```
This will unmount the file system, and detach the loop device.
Mac OS X
--------
### Using the GUI
Simply double-click on the image file in Mac OS X Finder.
### Using a Terminal Window
Use the [hdiutil](https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/hdiutil.1.html)
command.
```sh
$ hdiutil attach foo.iso
```
The output will show the `/dev` entry assigned as well as the mount point,
which is where you may now read the files in the image's file system.
To detach:
```sh
$ hdiutil detach foo.iso
```
Windows
-------
Windows 8 and later versions support mounting ISO images as a virtual drive.
### Using the GUI
1. In *File Explorer*, right-click on "foo.iso".
2. Select "Mount"
File Explorer then redirects to showing the files on your virtual drive. You can then use the [command line tool](dependency-check-cli/) to scan the
virtual drive. When finished, "Windows-E" will open File Explorer showing the various drives on your computer. To eject the virtual drive:
1. Right-click on the virtual drive.
2. Select "Eject"
### Using PowerShell
To mount, use the [Mount-DiskImage](https://technet.microsoft.com/en-us/%5Clibrary/Hh848706%28v=WPS.630%29.aspx)
cmdlet:
```posh
$ Mount-DiskImage -ImagePath C:\Full\Path\to\foo.iso
```
To view all drives (and find your virtual drive), use the
[Get-PSDrive](https://technet.microsoft.com/en-us/library/Hh849796.aspx)
cmdlet:
```posh
$ Get-PSDrive -PSProvider 'FileSystem'
```
To dismount, use the [Dismount-DiskImage](https://technet.microsoft.com/en-us/library/hh848693%28v=wps.630%29.aspx)
cmdlet:
```posh
$ Dismount-DiskImage -ImagePath C:\Full\Path\to\file.iso
```
### Windows 7
Third-party tools exist that can be used to mount ISO images. Without such
tools, it is still possible to burn the ISO image to physical media, and scan
the media:
1. Right-click on "foo.iso"
2. Select "Windows Disc Image Burner"
3. Follow the instructions to burn the image.
### Windows Vista
Just as with Windows 7, you will need a third-party tool to mount an ISO
image. You will also need a third-party tool to burn the image to media.
Many machines are shipped with such a tool included.

View File

@@ -102,31 +102,34 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
<item name="Sample Report" href="./general/SampleReport.html">
<description>Sample Report</description>
</item>
<item name="How to Scan an ISO Image" href="./general/scan_iso.html">
<description>How to Scan an ISO Image</description>
</item>
</item>
<item collapse="true" name="File Type Analyzers" href="./analyzers/index.html">
<item name="Archive Analyzer" href="./analyzers/archive-analyzer.html">
<description>Archive Analyzer</description>
</item>
<item name="Jar Analyzer" href="./analyzers/jar-analyzer.html">
<description>Jar Analyzer</description>
<item name="Assembly Analyzer" href="./analyzers/assembly-analyzer.html">
<description>Assembly Analyzer</description>
</item>
<item name="Python Analyzer" href="./analyzers/python-analyzer.html">
<description>Python Analyzer</description>
<item name="Autoconf Analyzer" href="./analyzers/autoconf-analyzer.html">
<description>Autoconf Analyzer</description>
</item>
<item name="Central Analyzer" href="./analyzers/central-analyzer.html">
<description>Central Analyzer</description>
</item>
<item name="Jar Analyzer" href="./analyzers/jar-analyzer.html">
<description>Jar Analyzer</description>
</item>
<item name="Nexus Analyzer" href="./analyzers/nexus-analyzer.html">
<description>Nexus Analyzer</description>
</item>
<item name="Assembly Analyzer" href="./analyzers/assembly-analyzer.html">
<description>Assembly Analyzer</description>
</item>
<item name="Nuspec Analyzer" href="./analyzers/nuspec-analyzer.html">
<description>Nuspec Analyzer</description>
</item>
<item name="Autoconf Analyzer" href="./analyzers/autoconf-analyzer.html">
<description>Autoconf Analyzer</description>
<item name="Python Analyzer" href="./analyzers/python-analyzer.html">
<description>Python Analyzer</description>
</item>
<item name="OpenSSL Analyzer" href="./analyzers/openssl-analyzer.html">
<description>OpenSSL Analyzer</description>