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