mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-03-26 19:11:29 +01:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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[
|
||||
|
||||
@@ -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 <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())
|
||||
|
||||
Reference in New Issue
Block a user