Skip to content

Commit e6b4443

Browse files
generic parser: handle is_mitigated and mitigated (#12167)
* generic parser: handle is_mitigated and mitigated * generic parser: handle is_mitigated and mitigated
1 parent b5eeb7f commit e6b4443

File tree

6 files changed

+101
-3
lines changed

6 files changed

+101
-3
lines changed

docs/content/en/connecting_your_tools/parsers/file/generic.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@ Attributes supported for CSV:
1818
- Verified: Indicator if the finding has been verified. Must be empty, TRUE, or FALSE
1919
- FalsePositive: Indicator if the finding is a false positive. Must be TRUE, or FALSE.
2020
- Duplicate:Indicator if the finding is a duplicate. Must be TRUE, or FALSE
21+
- IsMitigated: Indicator if the finding is mitigated. Must be TRUE, or FALSE
22+
- MitigatedDate: Date the finding was mitigated in mm/dd/yyyy format or ISO format
2123

2224
The CSV expects a header row with the names of the attributes.
2325

26+
Date fields are parsed using [dateutil.parse](https://dateutil.readthedocs.io/en/stable/parser.html) supporting a variety of formats such a YYYY-MM-DD or ISO-8601.
27+
2428
Example of JSON format:
2529

2630
```JSON
@@ -70,6 +74,34 @@ Example of JSON format:
7074
"cvssv3": "CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N",
7175
"file_path": "src/threeeeeeeeee.cpp",
7276
"line": 1353
77+
},
78+
{
79+
"title": "test title mitigated",
80+
"description": "Some very long description with\n\n some UTF-8 chars à qu'il est beau2",
81+
"severity": "Critical",
82+
"mitigation": "Some mitigation",
83+
"date": "2021-01-06",
84+
"cve": "CVE-2020-36236",
85+
"cwe": 287,
86+
"cvssv3": "CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N",
87+
"file_path": "src/threeeeeeeeee.cpp",
88+
"line": 1353,
89+
"is_mitigated": true,
90+
"mitigated": "2021-01-16"
91+
},
92+
{
93+
"title": "test title mitigated ISO",
94+
"description": "Some very long description with\n\n some UTF-8 chars à qu'il est beau2",
95+
"severity": "Critical",
96+
"mitigation": "Some mitigation",
97+
"date": "2024-01-04T11:02:11Z",
98+
"cve": "CVE-2020-36236",
99+
"cwe": 287,
100+
"cvssv3": "CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N",
101+
"file_path": "src/threeeeeeeeee.cpp",
102+
"line": 1353,
103+
"is_mitigated": true,
104+
"mitigated": "2024-01-24T11:02:11Z"
73105
}
74106
]
75107
}

dojo/tools/generic/csv_parser.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ def _get_findings_csv(self, filename):
3434
# manage active
3535
if "Active" in row:
3636
finding.active = self._convert_bool(row.get("Active"))
37+
if "IsMitigated" in row:
38+
finding.is_mitigated = self._convert_bool(row.get("IsMitigated"))
39+
if "MitigatedDate" in row:
40+
finding.mitigated = parse(row["MitigatedDate"])
3741
# manage mitigation
3842
if "Mitigation" in row:
3943
finding.mitigation = row["Mitigation"]

dojo/tools/generic/json_parser.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import base64
22

3+
import dateutil
34
from django.core.files.base import ContentFile
45

56
from dojo.models import Endpoint, FileUpload, Finding
@@ -39,6 +40,13 @@ def _get_test_json(self, data):
3940
del item["vulnerability_ids"]
4041
# check for required keys
4142
required = {"title", "severity", "description"}
43+
44+
if "date" in item:
45+
item["date"] = dateutil.parser.parse(item["date"]).date()
46+
47+
if "mitigated" in item:
48+
item["mitigated"] = dateutil.parser.parse(item["mitigated"])
49+
4250
missing = sorted(required.difference(item))
4351
if missing:
4452
msg = f"Required fields are missing: {missing}"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Date,Title,CweId,Url,Severity,Description,Mitigation,Impact,References,Active,Verified,FalsePositive,Duplicate,IsMitigated,MitigatedDate
2+
2024-01-24T11:02:11Z,Mitigated_ISO_Finding,4,https://vulnerable.endpoint.com/resource4/asdf,Low,Some description,Some mitigation advice,Some Impact,,TRUE,TRUE,FALSE,FALSE,TRUE,2024-02-24T11:02:11Z
3+
28/02/2021,Mitigated_Finding,5,https://vulnerable.endpoint.com/resource5/asdf,Low,Some description,Some mitigation advice,Some Impact,,TRUE,TRUE,FALSE,FALSE,TRUE,28/03/2021

unittests/scans/generic/generic_report3.json

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
]
3535
},
3636
{
37-
"title": "test title",
37+
"title": "test title mitigated",
3838
"description": "Some very long description with\n\n some UTF-8 chars à qu'il est beau2",
3939
"severity": "Critical",
4040
"mitigation": "Some mitigation",
@@ -43,7 +43,23 @@
4343
"cwe": 287,
4444
"cvssv3": "CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N",
4545
"file_path": "src/threeeeeeeeee.cpp",
46-
"line": 1353
46+
"line": 1353,
47+
"is_mitigated": true,
48+
"mitigated": "2021-01-16"
49+
},
50+
{
51+
"title": "test title mitigated ISO",
52+
"description": "Some very long description with\n\n some UTF-8 chars à qu'il est beau2",
53+
"severity": "Critical",
54+
"mitigation": "Some mitigation",
55+
"date": "2024-01-04T11:02:11Z",
56+
"cve": "CVE-2020-36236",
57+
"cwe": 287,
58+
"cvssv3": "CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N",
59+
"file_path": "src/threeeeeeeeee.cpp",
60+
"line": 1353,
61+
"is_mitigated": true,
62+
"mitigated": "2024-01-24T11:02:11Z"
4763
}
4864
]
4965
}

unittests/tools/test_generic_parser.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ def test_parse_json3(self):
491491
with open(get_unit_tests_scans_path("generic") / "generic_report3.json", encoding="utf-8") as file:
492492
parser = GenericParser()
493493
findings = parser.get_findings(file, Test())
494-
self.assertEqual(3, len(findings))
494+
self.assertEqual(4, len(findings))
495495
with self.subTest(i=0):
496496
finding = findings[0]
497497
finding.clean()
@@ -524,6 +524,21 @@ def test_parse_json3(self):
524524
self.assertEqual("urlfiltering.paloaltonetworks.com", endpoint.host)
525525
self.assertEqual(2345, endpoint.port)
526526
self.assertEqual("test-pest", endpoint.path)
527+
with self.subTest(i=2):
528+
finding = findings[2]
529+
self.assertEqual("test title mitigated", finding.title)
530+
self.assertEqual(True, finding.active)
531+
self.assertEqual(False, finding.duplicate)
532+
self.assertEqual(True, finding.is_mitigated)
533+
self.assertEqual(datetime.date(2021, 1, 16), finding.mitigated.date())
534+
with self.subTest(i=3):
535+
finding = findings[3]
536+
self.assertEqual("test title mitigated ISO", finding.title)
537+
self.assertEqual(True, finding.active)
538+
self.assertEqual(False, finding.duplicate)
539+
self.assertEqual(True, finding.is_mitigated)
540+
self.assertEqual(datetime.date(2024, 1, 4), finding.date)
541+
self.assertEqual(datetime.date(2024, 1, 24), finding.mitigated.date())
527542

528543
def test_parse_endpoints_and_vulnerability_ids_json(self):
529544
with open(get_unit_tests_scans_path("generic") / "generic_report4.json", encoding="utf-8") as file:
@@ -556,6 +571,26 @@ def test_parse_endpoints_and_vulnerability_ids_json(self):
556571
self.assertEqual("GHSA-5mrr-rgp6-x4gr", finding.unsaved_vulnerability_ids[0])
557572
self.assertEqual("CVE-2015-9235", finding.unsaved_vulnerability_ids[1])
558573

574+
def test_mitigated_csv_findings(self):
575+
with open(get_unit_tests_scans_path("generic") / "generic_report3.csv", encoding="utf-8") as file:
576+
parser = GenericParser()
577+
findings = parser.get_findings(file, Test())
578+
self.assertEqual(2, len(findings))
579+
580+
finding = findings[0]
581+
finding.clean()
582+
self.assertEqual("Mitigated_ISO_Finding", finding.title)
583+
self.assertEqual(datetime.date(2024, 1, 24), finding.date)
584+
self.assertEqual(True, finding.is_mitigated)
585+
self.assertEqual(datetime.date(2024, 2, 24), finding.mitigated.date())
586+
587+
finding = findings[1]
588+
finding.clean()
589+
self.assertEqual("Mitigated_Finding", finding.title)
590+
self.assertEqual(datetime.date(2021, 2, 28), finding.date)
591+
self.assertEqual(True, finding.is_mitigated)
592+
self.assertEqual(datetime.date(2021, 3, 28), finding.mitigated.date())
593+
559594
def test_parse_host_and_vulnerability_id_csv(self):
560595
with open(get_unit_tests_scans_path("generic") / "generic_report4.csv", encoding="utf-8") as file:
561596
parser = GenericParser()

0 commit comments

Comments
 (0)