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