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