mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-05-01 12:44:33 +02:00
Merge pull request #312 from dwvisser/rubygems-analyzer-pr
Rubygems analyzer
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -16,4 +16,5 @@ org.owasp.dependencycheck.analyzer.PythonDistributionAnalyzer
|
||||
org.owasp.dependencycheck.analyzer.PythonPackageAnalyzer
|
||||
org.owasp.dependencycheck.analyzer.AutoconfAnalyzer
|
||||
org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer
|
||||
org.owasp.dependencycheck.analyzer.CMakeAnalyzer
|
||||
org.owasp.dependencycheck.analyzer.CMakeAnalyzer
|
||||
org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer
|
||||
Reference in New Issue
Block a user