1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.owasp.dependencycheck.dependency;
19
20 import io.github.jeremylong.openvulnerability.client.nvd.CvssV2;
21 import io.github.jeremylong.openvulnerability.client.nvd.CvssV3;
22 import java.io.Serializable;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Set;
28 import javax.annotation.concurrent.NotThreadSafe;
29
30 import org.apache.commons.lang3.builder.CompareToBuilder;
31 import org.apache.commons.lang3.builder.EqualsBuilder;
32 import org.apache.commons.lang3.builder.HashCodeBuilder;
33 import org.jetbrains.annotations.NotNull;
34 import org.owasp.dependencycheck.utils.SeverityUtil;
35
36
37
38
39
40
41 @NotThreadSafe
42 public class Vulnerability implements Serializable, Comparable<Vulnerability> {
43
44
45
46
47 public enum Source {
48
49
50
51 NVD,
52
53
54
55 NPM,
56
57
58
59 RETIREJS,
60
61
62
63 OSSINDEX,
64
65
66
67 BUNDLEAUDIT,
68
69
70
71 MIXAUDIT
72 }
73
74
75
76
77 private static final long serialVersionUID = 307319490326651053L;
78
79
80
81
82 private String name;
83
84
85
86 private String description;
87
88
89
90 private org.owasp.dependencycheck.data.knownexploited.json.Vulnerability knownExploitedVulnerability;
91
92
93
94 private final Set<Reference> references = Collections.synchronizedSet(new HashSet<>());
95
96
97
98 private final Set<VulnerableSoftware> vulnerableSoftware = new HashSet<>();
99
100
101
102 private final CweSet cwes = new CweSet();
103
104
105
106
107
108
109 private String unscoredSeverity;
110
111
112
113 private CvssV2 cvssV2;
114
115
116
117
118 private CvssV3 cvssV3;
119
120
121
122
123 private VulnerableSoftware matchedVulnerableSoftware;
124
125
126
127
128 private String notes;
129
130
131
132
133 private Source source = null;
134
135
136
137
138 public Vulnerability() {
139
140 }
141
142
143
144
145
146
147 public Vulnerability(String name) {
148 this.name = name;
149 }
150
151
152
153
154
155
156 public String getName() {
157 return name;
158 }
159
160
161
162
163
164
165 public void setName(String name) {
166 this.name = name;
167 }
168
169
170
171
172
173
174 public String getDescription() {
175 return description;
176 }
177
178
179
180
181
182
183 public void setDescription(String description) {
184 this.description = description;
185 }
186
187
188
189
190
191
192 public Set<Reference> getReferences() {
193 return references;
194 }
195
196
197
198
199
200
201
202
203 public List<Reference> getReferences(boolean sorted) {
204 final List<Reference> sortedRefs = new ArrayList<>(this.references);
205 if (sorted) {
206 Collections.sort(sortedRefs);
207 }
208 return sortedRefs;
209 }
210
211
212
213
214
215
216 public void addReferences(Set<Reference> references) {
217 this.references.addAll(references);
218 }
219
220
221
222
223
224
225 public void addReference(Reference ref) {
226 this.references.add(ref);
227 }
228
229
230
231
232
233
234
235
236 public void addReference(String referenceSource, String referenceName, String referenceUrl) {
237 final Reference ref = new Reference();
238 ref.setSource(referenceSource);
239 ref.setName(referenceName);
240 ref.setUrl(referenceUrl);
241 this.references.add(ref);
242 }
243
244
245
246
247
248
249 public void setKnownExploitedVulnerability(org.owasp.dependencycheck.data.knownexploited.json.Vulnerability kev) {
250 this.knownExploitedVulnerability = kev;
251 }
252
253
254
255
256
257 public org.owasp.dependencycheck.data.knownexploited.json.Vulnerability getKnownExploitedVulnerability() {
258 return knownExploitedVulnerability;
259 }
260
261
262
263
264
265 public Set<VulnerableSoftware> getVulnerableSoftware() {
266 return vulnerableSoftware;
267 }
268
269
270
271
272
273
274
275
276 @SuppressWarnings("unchecked")
277 public List<VulnerableSoftware> getVulnerableSoftware(boolean sorted) {
278 synchronized (vulnerableSoftware) {
279 final List<VulnerableSoftware> sortedVulnerableSoftware = new ArrayList<>(this.vulnerableSoftware);
280 if (sorted) {
281 Collections.sort(sortedVulnerableSoftware);
282 }
283 return sortedVulnerableSoftware;
284 }
285 }
286
287
288
289
290
291
292 public void addVulnerableSoftware(Set<VulnerableSoftware> vulnerableSoftware) {
293 this.vulnerableSoftware.addAll(vulnerableSoftware);
294 }
295
296
297
298
299
300
301 public void addVulnerableSoftware(VulnerableSoftware software) {
302 vulnerableSoftware.add(software);
303 }
304
305
306
307
308
309
310 public CvssV2 getCvssV2() {
311 return cvssV2;
312 }
313
314
315
316
317
318
319 public void setCvssV2(CvssV2 cvssV2) {
320 this.cvssV2 = cvssV2;
321 }
322
323
324
325
326
327
328 public CvssV3 getCvssV3() {
329 return cvssV3;
330 }
331
332
333
334
335
336
337 public void setCvssV3(CvssV3 cvssV3) {
338 this.cvssV3 = cvssV3;
339 }
340
341
342
343
344
345
346 public CweSet getCwes() {
347 return cwes;
348 }
349
350
351
352
353
354
355 public void addCwe(String cwe) {
356 this.cwes.addCwe(cwe);
357 }
358
359
360
361
362
363
364
365
366
367 public String getUnscoredSeverity() {
368 return unscoredSeverity;
369 }
370
371
372
373
374
375
376
377
378
379 public void setUnscoredSeverity(String unscoredSeverity) {
380 this.unscoredSeverity = unscoredSeverity;
381 }
382
383
384
385
386
387
388 public String getNotes() {
389 return notes;
390 }
391
392
393
394
395
396
397 public void setNotes(String notes) {
398 this.notes = notes;
399 }
400
401 @Override
402 public boolean equals(Object obj) {
403 if (obj == null || !(obj instanceof Vulnerability)) {
404 return false;
405 }
406 if (this == obj) {
407 return true;
408 }
409 final Vulnerability other = (Vulnerability) obj;
410 return new EqualsBuilder()
411 .append(name, other.name)
412 .isEquals();
413 }
414
415 @Override
416 public int hashCode() {
417 return new HashCodeBuilder(3, 73)
418 .append(name)
419 .toHashCode();
420 }
421
422 @Override
423 public String toString() {
424 final StringBuilder sb = new StringBuilder("Vulnerability ");
425 sb.append(this.name);
426 sb.append("\nReferences:\n");
427 for (Reference reference : getReferences(true)) {
428 sb.append("=> ");
429 sb.append(reference);
430 sb.append("\n");
431 }
432 sb.append("\nSoftware:\n");
433
434 for (VulnerableSoftware software : getVulnerableSoftware(true)) {
435 sb.append("=> ");
436 sb.append(software);
437 sb.append("\n");
438 }
439 return sb.toString();
440 }
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467 @Override
468 public int compareTo(@NotNull Vulnerability o) {
469 return new CompareToBuilder()
470 .append(o.bestEffortSeverityLevelForSorting(), this.bestEffortSeverityLevelForSorting())
471 .append(this.name, o.name)
472 .toComparison();
473 }
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495 private Double bestEffortSeverityLevelForSorting() {
496 if (this.cvssV3 != null) {
497 return SeverityUtil.sortAdjustedCVSSv3BaseScore(this.cvssV3.getCvssData().getBaseScore());
498 }
499 if (this.cvssV2 != null) {
500 return this.cvssV2.getCvssData().getBaseScore();
501 }
502 return SeverityUtil.estimatedSortAdjustedCVSSv3(this.unscoredSeverity);
503 }
504
505
506
507
508
509
510
511
512 public String getHighestSeverityText() {
513 if (this.cvssV3 != null) {
514 return this.cvssV3.getCvssData().getBaseSeverity().value().toUpperCase();
515 }
516 if (this.cvssV2 != null) {
517 return this.cvssV2.getCvssData().getBaseSeverity().toUpperCase();
518 }
519 return SeverityUtil.unscoredToSeveritytext(this.unscoredSeverity).toUpperCase();
520 }
521
522
523
524
525
526
527 public void setMatchedVulnerableSoftware(VulnerableSoftware software) {
528 matchedVulnerableSoftware = software;
529 }
530
531
532
533
534
535
536 public VulnerableSoftware getMatchedVulnerableSoftware() {
537 return matchedVulnerableSoftware;
538 }
539
540
541
542
543
544
545 public Source getSource() {
546 return source;
547 }
548
549
550
551
552
553
554 public void setSource(Source source) {
555 this.source = source;
556 }
557 }