mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-03-22 09:09:31 +01:00
merge conflict resolved
This commit is contained in:
@@ -126,9 +126,8 @@ public class Engine implements FileFilter {
|
||||
}
|
||||
|
||||
final AnalyzerService service = new AnalyzerService(serviceClassLoader);
|
||||
final Iterator<Analyzer> iterator = service.getAnalyzers();
|
||||
while (iterator.hasNext()) {
|
||||
final Analyzer a = iterator.next();
|
||||
final List<Analyzer> iterator = service.getAnalyzers();
|
||||
for (Analyzer a : iterator) {
|
||||
analyzers.get(a.getAnalysisPhase()).add(a);
|
||||
if (a instanceof FileTypeAnalyzer) {
|
||||
this.fileTypeAnalyzers.add((FileTypeAnalyzer) a);
|
||||
|
||||
@@ -24,7 +24,6 @@ import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
import org.owasp.dependencycheck.suppression.SuppressionParseException;
|
||||
import org.owasp.dependencycheck.suppression.SuppressionParser;
|
||||
@@ -38,7 +37,8 @@ import org.slf4j.LoggerFactory;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Abstract base suppression analyzer that contains methods for parsing the suppression xml file.
|
||||
* Abstract base suppression analyzer that contains methods for parsing the
|
||||
* suppression xml file.
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
@@ -173,7 +173,8 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
|
||||
*
|
||||
* @param message the exception message
|
||||
* @param exception the cause of the exception
|
||||
* @throws SuppressionParseException throws the generated SuppressionParseException
|
||||
* @throws SuppressionParseException throws the generated
|
||||
* SuppressionParseException
|
||||
*/
|
||||
private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException {
|
||||
LOGGER.warn(message);
|
||||
|
||||
@@ -17,8 +17,13 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The Analyzer Service Loader. This class loads all services that implement
|
||||
@@ -27,11 +32,15 @@ import java.util.ServiceLoader;
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
public class AnalyzerService {
|
||||
/**
|
||||
* The Logger for use throughout the class.
|
||||
*/
|
||||
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(AnalyzerService.class);
|
||||
|
||||
/**
|
||||
* The service loader for analyzers.
|
||||
*/
|
||||
private final ServiceLoader<Analyzer> loader;
|
||||
private final ServiceLoader<Analyzer> service;
|
||||
|
||||
/**
|
||||
* Creates a new instance of AnalyzerService.
|
||||
@@ -39,15 +48,31 @@ public class AnalyzerService {
|
||||
* @param classLoader the ClassLoader to use when dynamically loading Analyzer and Update services
|
||||
*/
|
||||
public AnalyzerService(ClassLoader classLoader) {
|
||||
loader = ServiceLoader.load(Analyzer.class, classLoader);
|
||||
service = ServiceLoader.load(Analyzer.class, classLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator for all instances of the Analyzer interface.
|
||||
* Returns a list of all instances of the Analyzer interface.
|
||||
*
|
||||
* @return an iterator of Analyzers.
|
||||
* @return a list of Analyzers.
|
||||
*/
|
||||
public Iterator<Analyzer> getAnalyzers() {
|
||||
return loader.iterator();
|
||||
public List<Analyzer> getAnalyzers() {
|
||||
final List<Analyzer> analyzers = new ArrayList<Analyzer>();
|
||||
final Iterator<Analyzer> iterator = service.iterator();
|
||||
boolean experimentalEnabled = false;
|
||||
try {
|
||||
experimentalEnabled = Settings.getBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false);
|
||||
} catch (InvalidSettingException ex) {
|
||||
LOGGER.error("invalide experimental setting", ex);
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
final Analyzer a = iterator.next();
|
||||
if (!experimentalEnabled && a.getClass().isAnnotationPresent(Experimental.class)) {
|
||||
continue;
|
||||
}
|
||||
LOGGER.debug("Loaded Analyzer {}", a.getName());
|
||||
analyzers.add(a);
|
||||
}
|
||||
return analyzers;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import java.util.regex.Pattern;
|
||||
* @author Dale Visser
|
||||
* @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project - Free Software Foundation (FSF)</a>
|
||||
*/
|
||||
@Experimental
|
||||
public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
|
||||
/**
|
||||
|
||||
@@ -50,6 +50,7 @@ import java.util.regex.Pattern;
|
||||
*
|
||||
* @author Dale Visser
|
||||
*/
|
||||
@Experimental
|
||||
public class CMakeAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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) 2016 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation used to flag an analyzer as experimental.
|
||||
*
|
||||
* @author jeremy long
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface Experimental {
|
||||
|
||||
}
|
||||
@@ -67,11 +67,13 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
// Python init files
|
||||
/**
|
||||
* Python init files
|
||||
*/
|
||||
private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[] {
|
||||
"__init__.py",
|
||||
"__init__.pyc",
|
||||
"__init__.pyo"
|
||||
"__init__.pyo",
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -60,7 +60,8 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Used to load a JAR file and collect information that can be used to determine the associated CPE.
|
||||
* Used to load a JAR file and collect information that can be used to determine
|
||||
* the associated CPE.
|
||||
*
|
||||
* @author Jeremy Long
|
||||
*/
|
||||
@@ -72,7 +73,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
*/
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzer.class);
|
||||
/**
|
||||
* The count of directories created during analysis. This is used for creating temporary directories.
|
||||
* The count of directories created during analysis. This is used for
|
||||
* creating temporary directories.
|
||||
*/
|
||||
private static int dirCount = 0;
|
||||
/**
|
||||
@@ -80,7 +82,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
*/
|
||||
private static final String NEWLINE = System.getProperty("line.separator");
|
||||
/**
|
||||
* A list of values in the manifest to ignore as they only result in false positives.
|
||||
* A list of values in the manifest to ignore as they only result in false
|
||||
* positives.
|
||||
*/
|
||||
private static final Set<String> IGNORE_VALUES = newHashSet(
|
||||
"Sun Java System Application Server");
|
||||
@@ -123,7 +126,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
"ipojo-extension",
|
||||
"eclipse-sourcereferences");
|
||||
/**
|
||||
* Deprecated Jar manifest attribute, that is, nonetheless, useful for analysis.
|
||||
* Deprecated Jar manifest attribute, that is, nonetheless, useful for
|
||||
* analysis.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private static final String IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID
|
||||
@@ -203,7 +207,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
//</editor-fold>
|
||||
|
||||
/**
|
||||
* Returns the key used in the properties file to reference the analyzer's enabled property.
|
||||
* Returns the key used in the properties file to reference the analyzer's
|
||||
* enabled property.
|
||||
*
|
||||
* @return the analyzer's enabled property setting key
|
||||
*/
|
||||
@@ -213,12 +218,13 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a specified JAR file and collects information from the manifest and checksums to identify the correct CPE
|
||||
* information.
|
||||
* Loads a specified JAR file and collects information from the manifest and
|
||||
* checksums to identify the correct CPE information.
|
||||
*
|
||||
* @param dependency the dependency to analyze.
|
||||
* @param engine the engine that is scanning the dependencies
|
||||
* @throws AnalysisException is thrown if there is an error reading the JAR file.
|
||||
* @throws AnalysisException is thrown if there is an error reading the JAR
|
||||
* file.
|
||||
*/
|
||||
@Override
|
||||
public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
|
||||
@@ -242,13 +248,15 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to find a pom.xml within the JAR file. If found it extracts information and adds it to the evidence. This will
|
||||
* attempt to interpolate the strings contained within the pom.properties if one exists.
|
||||
* Attempts to find a pom.xml within the JAR file. If found it extracts
|
||||
* information and adds it to the evidence. This will attempt to interpolate
|
||||
* the strings contained within the pom.properties if one exists.
|
||||
*
|
||||
* @param dependency the dependency being analyzed
|
||||
* @param classes a collection of class name information
|
||||
* @param engine the analysis engine, used to add additional dependencies
|
||||
* @throws AnalysisException is thrown if there is an exception parsing the pom
|
||||
* @throws AnalysisException is thrown if there is an exception parsing the
|
||||
* pom
|
||||
* @return whether or not evidence was added to the dependency
|
||||
*/
|
||||
protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException {
|
||||
@@ -329,12 +337,14 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a path to a pom.xml within a JarFile, this method attempts to load a sibling pom.properties if one exists.
|
||||
* Given a path to a pom.xml within a JarFile, this method attempts to load
|
||||
* a sibling pom.properties if one exists.
|
||||
*
|
||||
* @param path the path to the pom.xml within the JarFile
|
||||
* @param jar the JarFile to load the pom.properties from
|
||||
* @return a Properties object or null if no pom.properties was found
|
||||
* @throws IOException thrown if there is an exception reading the pom.properties
|
||||
* @throws IOException thrown if there is an exception reading the
|
||||
* pom.properties
|
||||
*/
|
||||
private Properties retrievePomProperties(String path, final JarFile jar) throws IOException {
|
||||
Properties pomProperties = null;
|
||||
@@ -361,7 +371,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches a JarFile for pom.xml entries and returns a listing of these entries.
|
||||
* Searches a JarFile for pom.xml entries and returns a listing of these
|
||||
* entries.
|
||||
*
|
||||
* @param jar the JarFile to search
|
||||
* @return a list of pom.xml entries
|
||||
@@ -388,8 +399,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* @param jar the jar file to extract the pom from
|
||||
* @param dependency the dependency being analyzed
|
||||
* @return returns the POM object
|
||||
* @throws AnalysisException is thrown if there is an exception extracting or parsing the POM
|
||||
* {@link org.owasp.dependencycheck.xml.pom.Model} object
|
||||
* @throws AnalysisException is thrown if there is an exception extracting
|
||||
* or parsing the POM {@link org.owasp.dependencycheck.xml.pom.Model} object
|
||||
*/
|
||||
private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException {
|
||||
InputStream input = null;
|
||||
@@ -447,9 +458,10 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
*
|
||||
* @param dependency the dependency to set data on
|
||||
* @param pom the information from the pom
|
||||
* @param classes a collection of ClassNameInformation - containing data about the fully qualified class names within the JAR
|
||||
* file being analyzed
|
||||
* @return true if there was evidence within the pom that we could use; otherwise false
|
||||
* @param classes a collection of ClassNameInformation - containing data
|
||||
* about the fully qualified class names within the JAR file being analyzed
|
||||
* @return true if there was evidence within the pom that we could use;
|
||||
* otherwise false
|
||||
*/
|
||||
public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) {
|
||||
boolean foundSomething = false;
|
||||
@@ -576,12 +588,15 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyzes the path information of the classes contained within the JarAnalyzer to try and determine possible vendor or
|
||||
* product names. If any are found they are stored in the packageVendor and packageProduct hashSets.
|
||||
* Analyzes the path information of the classes contained within the
|
||||
* JarAnalyzer to try and determine possible vendor or product names. If any
|
||||
* are found they are stored in the packageVendor and packageProduct
|
||||
* hashSets.
|
||||
*
|
||||
* @param classNames a list of class names
|
||||
* @param dependency a dependency to analyze
|
||||
* @param addPackagesAsEvidence a flag indicating whether or not package names should be added as evidence.
|
||||
* @param addPackagesAsEvidence a flag indicating whether or not package
|
||||
* names should be added as evidence.
|
||||
*/
|
||||
protected void analyzePackageNames(List<ClassNameInformation> classNames,
|
||||
Dependency dependency, boolean addPackagesAsEvidence) {
|
||||
@@ -616,11 +631,13 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Reads the manifest from the JAR file and collects the entries. Some vendorKey entries are:</p>
|
||||
* Reads the manifest from the JAR file and collects the entries. Some
|
||||
* vendorKey entries are:</p>
|
||||
* <ul><li>Implementation Title</li>
|
||||
* <li>Implementation Version</li> <li>Implementation Vendor</li>
|
||||
* <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle Version</li> <li>Bundle Vendor</li> <li>Bundle
|
||||
* Description</li> <li>Main Class</li> </ul>
|
||||
* <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle
|
||||
* Version</li> <li>Bundle Vendor</li> <li>Bundle Description</li> <li>Main
|
||||
* Class</li> </ul>
|
||||
* However, all but a handful of specific entries are read in.
|
||||
*
|
||||
* @param dependency A reference to the dependency
|
||||
@@ -628,7 +645,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* @return whether evidence was identified parsing the manifest
|
||||
* @throws IOException if there is an issue reading the JAR file
|
||||
*/
|
||||
protected boolean parseManifest(Dependency dependency, List<ClassNameInformation> classInformation) throws IOException {
|
||||
protected boolean parseManifest(Dependency dependency, List<ClassNameInformation> classInformation)
|
||||
throws IOException {
|
||||
boolean foundSomething = false;
|
||||
JarFile jar = null;
|
||||
try {
|
||||
@@ -753,21 +771,19 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
addMatchingValues(classInformation, value, productEvidence);
|
||||
} else if (key.contains("license")) {
|
||||
addLicense(dependency, value);
|
||||
} else if (key.contains("description")) {
|
||||
addDescription(dependency, value, "manifest", key);
|
||||
} else {
|
||||
if (key.contains("description")) {
|
||||
addDescription(dependency, value, "manifest", key);
|
||||
} else {
|
||||
productEvidence.addEvidence(source, key, value, Confidence.LOW);
|
||||
vendorEvidence.addEvidence(source, key, value, Confidence.LOW);
|
||||
addMatchingValues(classInformation, value, vendorEvidence);
|
||||
addMatchingValues(classInformation, value, productEvidence);
|
||||
if (value.matches(".*\\d.*")) {
|
||||
final StringTokenizer tokenizer = new StringTokenizer(value, " ");
|
||||
while (tokenizer.hasMoreElements()) {
|
||||
final String s = tokenizer.nextToken();
|
||||
if (s.matches("^[0-9.]+$")) {
|
||||
versionEvidence.addEvidence(source, key, s, Confidence.LOW);
|
||||
}
|
||||
productEvidence.addEvidence(source, key, value, Confidence.LOW);
|
||||
vendorEvidence.addEvidence(source, key, value, Confidence.LOW);
|
||||
addMatchingValues(classInformation, value, vendorEvidence);
|
||||
addMatchingValues(classInformation, value, productEvidence);
|
||||
if (value.matches(".*\\d.*")) {
|
||||
final StringTokenizer tokenizer = new StringTokenizer(value, " ");
|
||||
while (tokenizer.hasMoreElements()) {
|
||||
final String s = tokenizer.nextToken();
|
||||
if (s.matches("^[0-9.]+$")) {
|
||||
versionEvidence.addEvidence(source, key, s, Confidence.LOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -815,15 +831,18 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a description to the given dependency. If the description contains one of the following strings beyond 100 characters,
|
||||
* then the description used will be trimmed to that position:
|
||||
* <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses "</li></ul>
|
||||
* Adds a description to the given dependency. If the description contains
|
||||
* one of the following strings beyond 100 characters, then the description
|
||||
* used will be trimmed to that position:
|
||||
* <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses
|
||||
* "</li></ul>
|
||||
*
|
||||
* @param dependency a dependency
|
||||
* @param description the description
|
||||
* @param source the source of the evidence
|
||||
* @param key the "name" of the evidence
|
||||
* @return if the description is trimmed, the trimmed version is returned; otherwise the original description is returned
|
||||
* @return if the description is trimmed, the trimmed version is returned;
|
||||
* otherwise the original description is returned
|
||||
*/
|
||||
public static String addDescription(Dependency dependency, String description, String source, String key) {
|
||||
if (dependency.getDescription() == null) {
|
||||
@@ -894,7 +913,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
/**
|
||||
* Initializes the JarAnalyzer.
|
||||
*
|
||||
* @throws Exception is thrown if there is an exception creating a temporary directory
|
||||
* @throws Exception is thrown if there is an exception creating a temporary
|
||||
* directory
|
||||
*/
|
||||
@Override
|
||||
public void initializeFileTypeAnalyzer() throws Exception {
|
||||
@@ -925,11 +945,13 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the key value pair from the manifest is for an "import" type entry for package names.
|
||||
* Determines if the key value pair from the manifest is for an "import"
|
||||
* type entry for package names.
|
||||
*
|
||||
* @param key the key from the manifest
|
||||
* @param value the value from the manifest
|
||||
* @return true or false depending on if it is believed the entry is an "import" entry
|
||||
* @return true or false depending on if it is believed the entry is an
|
||||
* "import" entry
|
||||
*/
|
||||
private boolean isImportPackage(String key, String value) {
|
||||
final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$");
|
||||
@@ -938,8 +960,9 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Cycles through an enumeration of JarEntries, contained within the dependency, and returns a list of the class names. This
|
||||
* does not include core Java package names (i.e. java.* or javax.*).
|
||||
* Cycles through an enumeration of JarEntries, contained within the
|
||||
* dependency, and returns a list of the class names. This does not include
|
||||
* core Java package names (i.e. java.* or javax.*).
|
||||
*
|
||||
* @param dependency the dependency being analyzed
|
||||
* @return an list of fully qualified class names
|
||||
@@ -975,12 +998,16 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Cycles through the list of class names and places the package levels 0-3 into the provided maps for vendor and product.
|
||||
* This is helpful when analyzing vendor/product as many times this is included in the package name.
|
||||
* Cycles through the list of class names and places the package levels 0-3
|
||||
* into the provided maps for vendor and product. This is helpful when
|
||||
* analyzing vendor/product as many times this is included in the package
|
||||
* name.
|
||||
*
|
||||
* @param classNames a list of class names
|
||||
* @param vendor HashMap of possible vendor names from package names (e.g. owasp)
|
||||
* @param product HashMap of possible product names from package names (e.g. dependencycheck)
|
||||
* @param vendor HashMap of possible vendor names from package names (e.g.
|
||||
* owasp)
|
||||
* @param product HashMap of possible product names from package names (e.g.
|
||||
* dependencycheck)
|
||||
*/
|
||||
private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames,
|
||||
Map<String, Integer> vendor, Map<String, Integer> product) {
|
||||
@@ -1007,8 +1034,9 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an entry to the specified collection and sets the Integer (e.g. the count) to 1. If the entry already exists in the
|
||||
* collection then the Integer is incremented by 1.
|
||||
* Adds an entry to the specified collection and sets the Integer (e.g. the
|
||||
* count) to 1. If the entry already exists in the collection then the
|
||||
* Integer is incremented by 1.
|
||||
*
|
||||
* @param collection a collection of strings and their occurrence count
|
||||
* @param key the key to add to the collection
|
||||
@@ -1022,9 +1050,10 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Cycles through the collection of class name information to see if parts of the package names are contained in the provided
|
||||
* value. If found, it will be added as the HIGHEST confidence evidence because we have more then one source corroborating the
|
||||
* value.
|
||||
* Cycles through the collection of class name information to see if parts
|
||||
* of the package names are contained in the provided value. If found, it
|
||||
* will be added as the HIGHEST confidence evidence because we have more
|
||||
* then one source corroborating the value.
|
||||
*
|
||||
* @param classes a collection of class name information
|
||||
* @param value the value to check to see if it contains a package name
|
||||
@@ -1047,7 +1076,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple check to see if the attribute from a manifest is just a package name.
|
||||
* Simple check to see if the attribute from a manifest is just a package
|
||||
* name.
|
||||
*
|
||||
* @param key the key of the value to check
|
||||
* @param value the value to check
|
||||
@@ -1061,7 +1091,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the license information from the pom and adds it to the dependency.
|
||||
* Extracts the license information from the pom and adds it to the
|
||||
* dependency.
|
||||
*
|
||||
* @param pom the pom object
|
||||
* @param dependency the dependency to add license information too
|
||||
@@ -1108,9 +1139,11 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Stores information about a given class name. This class will keep the fully qualified class name and a list of the
|
||||
* important parts of the package structure. Up to the first four levels of the package structure are stored, excluding a
|
||||
* leading "org" or "com". Example:</p>
|
||||
* Stores information about a given class name. This class will keep the
|
||||
* fully qualified class name and a list of the important parts of the
|
||||
* package structure. Up to the first four levels of the package
|
||||
* structure are stored, excluding a leading "org" or "com".
|
||||
* Example:</p>
|
||||
* <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer");
|
||||
* System.out.println(obj.getName());
|
||||
* for (String p : obj.getPackageStructure())
|
||||
@@ -1169,7 +1202,8 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
this.name = name;
|
||||
}
|
||||
/**
|
||||
* Up to the first four levels of the package structure, excluding a leading "org" or "com".
|
||||
* Up to the first four levels of the package structure, excluding a
|
||||
* leading "org" or "com".
|
||||
*/
|
||||
private final ArrayList<String> packageStructure = new ArrayList<String>();
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ import javax.json.JsonValue;
|
||||
*
|
||||
* @author Dale Visser
|
||||
*/
|
||||
@Experimental
|
||||
public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,16 @@
|
||||
*/
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.nio.charset.Charset;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
@@ -29,11 +39,6 @@ import org.owasp.dependencycheck.utils.FileFilterBuilder;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||
|
||||
/**
|
||||
@@ -63,9 +68,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
public static final String ADVISORY = "Advisory: ";
|
||||
public static final String CRITICALITY = "Criticality: ";
|
||||
|
||||
public CveDB cvedb;
|
||||
//instance.open();
|
||||
//Vulnerability result = instance.getVulnerability("CVE-2015-3225");
|
||||
private CveDB cvedb;
|
||||
|
||||
/**
|
||||
* @return a filter that accepts files named Gemfile.lock
|
||||
@@ -207,11 +210,10 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
boolean failed = true;
|
||||
final String className = RubyGemspecAnalyzer.class.getName();
|
||||
for (FileTypeAnalyzer analyzer : engine.getFileTypeAnalyzers()) {
|
||||
if (analyzer instanceof RubyBundlerAnalyzer) {
|
||||
if (analyzer instanceof RubyBundlerAnalyzer) {
|
||||
((RubyBundlerAnalyzer) analyzer).setEnabled(false);
|
||||
LOGGER.info("Disabled " + RubyBundlerAnalyzer.class.getName() + " to avoid noisy duplicate results.");
|
||||
}
|
||||
else if (analyzer instanceof RubyGemspecAnalyzer) {
|
||||
} else if (analyzer instanceof RubyGemspecAnalyzer) {
|
||||
((RubyGemspecAnalyzer) analyzer).setEnabled(false);
|
||||
LOGGER.info("Disabled " + className + " to avoid noisy duplicate results.");
|
||||
failed = false;
|
||||
@@ -230,8 +232,9 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
throw new AnalysisException("bundle-audit process interrupted", ie);
|
||||
}
|
||||
BufferedReader rdr = null;
|
||||
BufferedReader errReader = null;
|
||||
try {
|
||||
BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
|
||||
errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
|
||||
while (errReader.ready()) {
|
||||
String error = errReader.readLine();
|
||||
LOGGER.warn(error);
|
||||
@@ -241,6 +244,13 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
} catch (IOException ioe) {
|
||||
LOGGER.warn("bundle-audit failure", ioe);
|
||||
} finally {
|
||||
if (errReader != null) {
|
||||
try {
|
||||
errReader.close();
|
||||
} catch (IOException ioe) {
|
||||
LOGGER.warn("bundle-audit close failure", ioe);
|
||||
}
|
||||
}
|
||||
if (null != rdr) {
|
||||
try {
|
||||
rdr.close();
|
||||
|
||||
@@ -261,6 +261,7 @@ public class DownloadTask implements Callable<Future<ProcessTask>> {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.debug("Error closing stream", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
@@ -110,7 +109,8 @@ public class SuppressionParser {
|
||||
*
|
||||
* @param inputStream an InputStream containing suppression rues
|
||||
* @return a list of suppression rules
|
||||
* @throws SuppressionParseException if the xml cannot be parsed
|
||||
* @throws SuppressionParseException thrown if the xml cannot be parsed
|
||||
* @throws SAXException thrown if the xml cannot be parsed
|
||||
*/
|
||||
public List<SuppressionRule> parseSuppressionRules(InputStream inputStream) throws SuppressionParseException, SAXException {
|
||||
try {
|
||||
|
||||
@@ -63,13 +63,6 @@ cve.url-2.0.base=https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml.gz
|
||||
cpe.validfordays=30
|
||||
cpe.url=http://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.3.xml.gz
|
||||
|
||||
# file type analyzer settings:
|
||||
analyzer.archive.enabled=true
|
||||
analyzer.jar.enabled=true
|
||||
analyzer.nuspec.enabled=true
|
||||
analyzer.assembly.enabled=true
|
||||
analyzer.composer.lock.enabled=true
|
||||
|
||||
# the URL for searching Nexus for SHA-1 hashes and whether it's enabled
|
||||
analyzer.nexus.enabled=true
|
||||
analyzer.nexus.url=https://repository.sonatype.org/service/local/
|
||||
@@ -87,7 +80,7 @@ archive.scan.depth=3
|
||||
# use HEAD (default) or GET as HTTP request method for query timestamp
|
||||
downloader.quick.query.timestamp=true
|
||||
|
||||
|
||||
analyzer.experimental.enabled=false
|
||||
analyzer.jar.enabled=true
|
||||
analyzer.archive.enabled=true
|
||||
analyzer.node.package.enabled=true
|
||||
|
||||
@@ -18,9 +18,12 @@
|
||||
package org.owasp.dependencycheck.analyzer;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
import org.owasp.dependencycheck.BaseDBTestCase;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -34,15 +37,42 @@ public class AnalyzerServiceTest extends BaseDBTestCase {
|
||||
@Test
|
||||
public void testGetAnalyzers() {
|
||||
AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader());
|
||||
Iterator<Analyzer> result = instance.getAnalyzers();
|
||||
List<Analyzer> result = instance.getAnalyzers();
|
||||
|
||||
boolean found = false;
|
||||
while (result.hasNext()) {
|
||||
Analyzer a = result.next();
|
||||
for (Analyzer a : result) {
|
||||
if ("Jar Analyzer".equals(a.getName())) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
assertTrue("JarAnalyzer loaded", found);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of getAnalyzers method, of class AnalyzerService.
|
||||
*/
|
||||
@Test
|
||||
public void testGetExperimentalAnalyzers() {
|
||||
Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false);
|
||||
AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader());
|
||||
List<Analyzer> result = instance.getAnalyzers();
|
||||
String experimental = "CMake Analyzer";
|
||||
boolean found = false;
|
||||
for (Analyzer a : result) {
|
||||
if (experimental.equals(a.getName())) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
assertFalse("Experimental analyzer loaded when set to false", found);
|
||||
|
||||
Settings.setBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, true);
|
||||
result = instance.getAnalyzers();
|
||||
found = false;
|
||||
for (Analyzer a : result) {
|
||||
if (experimental.equals(a.getName())) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
assertTrue("Experimental analyzer not loaded when set to true", found);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase {
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
Settings.initialize();
|
||||
Settings.initialize();
|
||||
analyzer = new RubyBundleAuditAnalyzer();
|
||||
analyzer.setFilesMatched(true);
|
||||
}
|
||||
@@ -77,7 +77,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase {
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
Settings.cleanup();
|
||||
Settings.cleanup();
|
||||
analyzer.close();
|
||||
analyzer = null;
|
||||
}
|
||||
@@ -105,7 +105,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase {
|
||||
*/
|
||||
@Test
|
||||
public void testAnalysis() throws AnalysisException, DatabaseException {
|
||||
try {
|
||||
try {
|
||||
analyzer.initialize();
|
||||
final String resource = "ruby/vulnerable/gems/rails-4.1.15/Gemfile.lock";
|
||||
final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, resource));
|
||||
@@ -139,7 +139,6 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase {
|
||||
final Engine engine = new Engine();
|
||||
analyzer.analyze(result, engine);
|
||||
|
||||
|
||||
Dependency dependency = engine.getDependencies().get(0);
|
||||
Vulnerability vulnerability = dependency.getVulnerabilities().first();
|
||||
assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0);
|
||||
@@ -150,7 +149,6 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test when Ruby bundle-audit is not available on the system.
|
||||
*
|
||||
@@ -158,17 +156,16 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase {
|
||||
*/
|
||||
@Test
|
||||
public void testMissingBundleAudit() throws AnalysisException, DatabaseException {
|
||||
//set a non-exist bundle-audit
|
||||
//set a non-exist bundle-audit
|
||||
Settings.setString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, "phantom-bundle-audit");
|
||||
try {
|
||||
//initialize should fail.
|
||||
analyzer.initialize();
|
||||
} catch (Exception e) {
|
||||
//expected, so ignore.
|
||||
}
|
||||
finally {
|
||||
assertThat(analyzer.isEnabled(), is(false));
|
||||
LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected.");
|
||||
analyzer.initialize();
|
||||
} catch (Exception e) {
|
||||
//expected, so ignore.
|
||||
} finally {
|
||||
assertThat(analyzer.isEnabled(), is(false));
|
||||
LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,12 +58,6 @@ cve.url-2.0.base=https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml.gz
|
||||
cpe.validfordays=30
|
||||
cpe.url=http://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.3.xml.gz
|
||||
|
||||
# file type analyzer settings:
|
||||
analyzer.archive.enabled=true
|
||||
analyzer.jar.enabled=true
|
||||
analyzer.nuspec.enabled=true
|
||||
analyzer.assembly.enabled=true
|
||||
analyzer.composer.lock.enabled=true
|
||||
|
||||
# the URL for searching Nexus for SHA-1 hashes and whether it's enabled
|
||||
analyzer.nexus.enabled=true
|
||||
@@ -82,7 +76,7 @@ archive.scan.depth=3
|
||||
# use HEAD (default) or GET as HTTP request method for query timestamp
|
||||
downloader.quick.query.timestamp=true
|
||||
|
||||
|
||||
analyzer.experimental.enabled=true
|
||||
analyzer.jar.enabled=true
|
||||
analyzer.archive.enabled=true
|
||||
analyzer.node.package.enabled=true
|
||||
|
||||
Reference in New Issue
Block a user