1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.owasp.dependencycheck.analyzer;
19
20 import org.apache.commons.io.FileUtils;
21 import org.owasp.dependencycheck.Engine;
22 import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
23 import org.owasp.dependencycheck.dependency.Confidence;
24 import org.owasp.dependencycheck.dependency.Dependency;
25 import org.owasp.dependencycheck.dependency.EvidenceCollection;
26 import org.owasp.dependencycheck.utils.FileFilterBuilder;
27 import org.owasp.dependencycheck.utils.Settings;
28
29 import java.io.FileFilter;
30 import java.io.IOException;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
33
34
35
36
37
38
39
40 public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
41
42
43
44
45 private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer";
46
47
48
49
50 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
51
52 private static final FileFilter FILTER =
53 FileFilterBuilder.newInstance().addExtensions("gemspec").addFilenames("Rakefile").build();
54
55 private static final String EMAIL = "email";
56 private static final String GEMSPEC = "gemspec";
57
58
59
60
61 @Override
62 protected FileFilter getFileFilter() {
63 return FILTER;
64 }
65
66 @Override
67 protected void initializeFileTypeAnalyzer() throws Exception {
68
69 }
70
71
72
73
74
75
76 @Override
77 public String getName() {
78 return ANALYZER_NAME;
79 }
80
81
82
83
84
85
86 @Override
87 public AnalysisPhase getAnalysisPhase() {
88 return ANALYSIS_PHASE;
89 }
90
91
92
93
94
95
96 @Override
97 protected String getAnalyzerEnabledSettingKey() {
98 return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED;
99 }
100
101
102
103
104 private static final Pattern GEMSPEC_BLOCK_INIT =
105 Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|");
106
107 @Override
108 protected void analyzeFileType(Dependency dependency, Engine engine)
109 throws AnalysisException {
110 String contents;
111 try {
112 contents = FileUtils.readFileToString(dependency.getActualFile());
113 } catch (IOException e) {
114 throw new AnalysisException(
115 "Problem occurred while reading dependency file.", e);
116 }
117 final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents);
118 if (matcher.find()) {
119 contents = contents.substring(matcher.end());
120 final String blockVariable = matcher.group(1);
121 final EvidenceCollection vendor = dependency.getVendorEvidence();
122 addStringEvidence(vendor, contents, blockVariable, "author", Confidence.HIGHEST);
123 addListEvidence(vendor, contents, blockVariable, "authors", Confidence.HIGHEST);
124 final String email = addStringEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM);
125 if (email.isEmpty()) {
126 addListEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM);
127 }
128 addStringEvidence(vendor, contents, blockVariable, "homepage", Confidence.MEDIUM);
129 final EvidenceCollection product = dependency.getProductEvidence();
130 final String name = addStringEvidence(product, contents, blockVariable, "name", Confidence.HIGHEST);
131 if (!name.isEmpty()) {
132 vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW);
133 }
134 addStringEvidence(product, contents, blockVariable, "summary", Confidence.LOW);
135 addStringEvidence(dependency.getVersionEvidence(), contents, blockVariable, "version", Confidence.HIGHEST);
136 }
137 }
138
139 private void addListEvidence(EvidenceCollection evidences, String contents,
140 String blockVariable, String field, Confidence confidence) {
141 final Matcher matcher = Pattern.compile(
142 String.format("\\s+?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, field)).matcher(contents);
143 if (matcher.find()) {
144 final String value = matcher.group(1).replaceAll("['\"]", " ").trim();
145 evidences.addEvidence(GEMSPEC, field, value, confidence);
146 }
147 }
148
149 private String addStringEvidence(EvidenceCollection evidences, String contents,
150 String blockVariable, String field, Confidence confidence) {
151 final Matcher matcher = Pattern.compile(
152 String.format("\\s+?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, field)).matcher(contents);
153 String value = "";
154 if (matcher.find()) {
155 value = matcher.group(2);
156 evidences.addEvidence(GEMSPEC, field, value, confidence);
157 }
158 return value;
159 }
160 }