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 static org.hamcrest.CoreMatchers.is;
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertThat;
23 import static org.junit.Assert.assertTrue;
24
25 import java.io.File;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Set;
29 import java.util.logging.Level;
30
31 import org.junit.After;
32 import org.junit.Assume;
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.owasp.dependencycheck.BaseDBTestCase;
36 import org.owasp.dependencycheck.BaseTest;
37 import org.owasp.dependencycheck.Engine;
38 import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
39 import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
40 import org.owasp.dependencycheck.dependency.Dependency;
41 import org.owasp.dependencycheck.dependency.Evidence;
42 import org.owasp.dependencycheck.dependency.Identifier;
43 import org.owasp.dependencycheck.dependency.Vulnerability;
44 import org.owasp.dependencycheck.exception.ExceptionCollection;
45 import org.owasp.dependencycheck.utils.Settings;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49
50
51
52
53
54 public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase {
55
56 private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzerTest.class);
57
58
59
60
61 RubyBundleAuditAnalyzer analyzer;
62
63
64
65
66
67
68 @Override
69 @Before
70 public void setUp() throws Exception {
71 super.setUp();
72 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
73 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false);
74 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false);
75 analyzer = new RubyBundleAuditAnalyzer();
76 analyzer.setFilesMatched(true);
77 }
78
79
80
81
82
83
84 @After
85 public void tearDown() throws Exception {
86 analyzer.close();
87 analyzer = null;
88 }
89
90
91
92
93 @Test
94 public void testGetName() {
95 assertThat(analyzer.getName(), is("Ruby Bundle Audit Analyzer"));
96 }
97
98
99
100
101 @Test
102 public void testSupportsFiles() {
103 assertThat(analyzer.accept(new File("Gemfile.lock")), is(true));
104 }
105
106
107
108
109
110
111 @Test
112 public void testAnalysis() throws AnalysisException, DatabaseException {
113 try {
114 analyzer.initialize();
115 final String resource = "ruby/vulnerable/gems/rails-4.1.15/Gemfile.lock";
116 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, resource));
117 final Engine engine = new Engine();
118 analyzer.analyze(result, engine);
119 int size = engine.getDependencies().size();
120 assertTrue(size >= 1);
121
122 Dependency dependency = engine.getDependencies().get(0);
123 assertTrue(dependency.getProductEvidence().toString().toLowerCase().contains("redcarpet"));
124 assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2"));
125 assertTrue(dependency.getFilePath().endsWith(resource));
126 assertTrue(dependency.getFileName().equals("Gemfile.lock"));
127 } catch (Exception e) {
128 LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\".");
129 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e);
130 }
131 }
132
133
134
135
136 @Test
137 public void testAddCriticalityToVulnerability() throws AnalysisException, DatabaseException {
138 try {
139 analyzer.initialize();
140
141 final Dependency result = new Dependency(BaseTest.getResourceAsFile(this,
142 "ruby/vulnerable/gems/sinatra/Gemfile.lock"));
143 final Engine engine = new Engine();
144 analyzer.analyze(result, engine);
145
146 Dependency dependency = engine.getDependencies().get(0);
147 Vulnerability vulnerability = dependency.getVulnerabilities().first();
148 assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0);
149
150 } catch (Exception e) {
151 LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\".");
152 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e);
153 }
154 }
155
156
157
158
159
160
161 @Test
162 public void testMissingBundleAudit() throws AnalysisException, DatabaseException {
163
164 Settings.setString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, "phantom-bundle-audit");
165 try {
166
167 analyzer.initialize();
168 } catch (Exception e) {
169
170 } finally {
171 assertThat(analyzer.isEnabled(), is(false));
172 LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected.");
173 }
174 }
175
176
177
178
179
180
181
182 @Test
183 public void testDependenciesPath() throws AnalysisException, DatabaseException {
184 final Engine engine = new Engine();
185 engine.scan(BaseTest.getResourceAsFile(this,
186 "ruby/vulnerable/gems/rails-4.1.15/"));
187 try {
188 engine.analyzeDependencies();
189 } catch (NullPointerException ex) {
190 LOGGER.error("NPE", ex);
191 throw ex;
192 } catch (ExceptionCollection ex) {
193 Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", ex);
194 }
195 List<Dependency> dependencies = engine.getDependencies();
196 LOGGER.info(dependencies.size() + " dependencies found.");
197 Iterator<Dependency> dIterator = dependencies.iterator();
198 while (dIterator.hasNext()) {
199 Dependency dept = dIterator.next();
200 LOGGER.info("dept path: " + dept.getActualFilePath());
201
202 Set<Identifier> identifiers = dept.getIdentifiers();
203 Iterator<Identifier> idIterator = identifiers.iterator();
204 while (idIterator.hasNext()) {
205 Identifier id = idIterator.next();
206 LOGGER.info(" Identifier: " + id.getValue() + ", type=" + id.getType() + ", url=" + id.getUrl() + ", conf=" + id.getConfidence());
207 }
208
209 Set<Evidence> prodEv = dept.getProductEvidence().getEvidence();
210 Iterator<Evidence> it = prodEv.iterator();
211 while (it.hasNext()) {
212 Evidence e = it.next();
213 LOGGER.info(" prod: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence());
214 }
215 Set<Evidence> versionEv = dept.getVersionEvidence().getEvidence();
216 Iterator<Evidence> vIt = versionEv.iterator();
217 while (vIt.hasNext()) {
218 Evidence e = vIt.next();
219 LOGGER.info(" version: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence());
220 }
221
222 Set<Evidence> vendorEv = dept.getVendorEvidence().getEvidence();
223 Iterator<Evidence> vendorIt = vendorEv.iterator();
224 while (vendorIt.hasNext()) {
225 Evidence e = vendorIt.next();
226 LOGGER.info(" vendor: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence());
227 }
228 }
229 }
230 }