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