Skip to content

Commit d519cf7

Browse files
authored
Merge pull request #13650 from DefectDojo/importing-tags
Improve tag handling in importers and add tests for tag imports
2 parents 0bc088c + 0523665 commit d519cf7

File tree

4 files changed

+70
-5
lines changed

4 files changed

+70
-5
lines changed

dojo/importers/default_importer.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,11 @@ def process_findings(
226226
# Process any endpoints on the endpoint, or added on the form
227227
self.process_endpoints(finding, self.endpoints_to_add)
228228
# Parsers must use unsaved_tags to store tags, so we can clean them
229-
finding.tags = clean_tags(finding.unsaved_tags)
229+
cleaned_tags = clean_tags(finding.unsaved_tags)
230+
if isinstance(cleaned_tags, list):
231+
finding.tags.set(cleaned_tags)
232+
elif isinstance(cleaned_tags, str):
233+
finding.tags.set([cleaned_tags])
230234
# Process any files
231235
self.process_files(finding)
232236
# Process vulnerability IDs

dojo/importers/default_reimporter.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -693,8 +693,12 @@ def finding_post_processing(
693693
if len(self.endpoints_to_add) > 0:
694694
self.endpoint_manager.chunk_endpoints_and_disperse(finding, self.endpoints_to_add)
695695
# Parsers must use unsaved_tags to store tags, so we can clean them
696-
if finding.unsaved_tags:
697-
finding.tags = clean_tags(finding.unsaved_tags)
696+
if finding_from_report.unsaved_tags:
697+
cleaned_tags = clean_tags(finding_from_report.unsaved_tags)
698+
if isinstance(cleaned_tags, list):
699+
finding.tags.set(cleaned_tags)
700+
elif isinstance(cleaned_tags, str):
701+
finding.tags.set([cleaned_tags])
698702
# Process any files
699703
if finding_from_report.unsaved_files:
700704
finding.unsaved_files = finding_from_report.unsaved_files
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"findings": [
3+
{
4+
"title": "test title",
5+
"description": "Some very long description with\n\n some UTF-8 chars à qu'il est beau",
6+
"active": true,
7+
"verified": true,
8+
"severity": "Medium",
9+
"impact": "Some impact",
10+
"date": "2021-01-06",
11+
"cve": "CVE-2020-36234",
12+
"cwe": 261,
13+
"cvssv3": "CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N",
14+
"tags": ["security", "network", "hardened"],
15+
"unique_id_from_tool": "3287f2d0-554f-491b-8516-3c349ead8ee5",
16+
"vuln_id_from_tool": "TEST1"
17+
},
18+
{
19+
"title": "test title2",
20+
"description": "Some very long description with\n\n some UTF-8 chars à qu'il est beau2",
21+
"active": true,
22+
"verified": false,
23+
"severity": "Medium",
24+
"impact": "Some impact",
25+
"date": "2021-01-06",
26+
"cve": "CVE-2020-36235",
27+
"cwe": 287,
28+
"cvssv3": "CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N",
29+
"tags": ["security", "network", "hardened"],
30+
"unique_id_from_tool": "42500af3-68c5-4dc3-8022-191d93c2f1f7",
31+
"vuln_id_from_tool": "TEST2"
32+
}
33+
]
34+
}

unittests/test_tags.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ class TagTests(DojoAPITestCase):
1515
def setUp(self, *args, **kwargs):
1616
super().setUp()
1717
self.login_as_admin()
18-
self.scans_path = get_unit_tests_scans_path("zap")
19-
self.zap_sample5_filename = self.scans_path / "5_zap_sample_one.xml"
18+
self.zap_sample5_filename = get_unit_tests_scans_path("zap") / "5_zap_sample_one.xml"
19+
self.generic_sample_with_tags_filename = get_unit_tests_scans_path("generic") / "generic_report1.json"
20+
self.generic_sample_with_more_tags_filename = get_unit_tests_scans_path("generic") / "generic_report1_more_tags.json"
2021

2122
def test_create_product_with_tags(self, expected_status_code: int = 201):
2223
product_id = Product.objects.all().first().id
@@ -285,6 +286,28 @@ def test_import_multipart_tags(self):
285286
for tag in success_tags:
286287
self.assertIn(tag, response["tags"])
287288

289+
def test_import_report_with_tags(self):
290+
def assert_tags_in_findings(findings: list[dict], expected_finding_count: int, desired_tags: list[str]) -> None:
291+
self.assertEqual(expected_finding_count, len(findings))
292+
for finding in findings:
293+
self.assertEqual(len(desired_tags), len(finding.get("tags")))
294+
for tag in desired_tags:
295+
self.assertIn(tag, finding["tags"])
296+
297+
# Import a report with findings that have tags
298+
import0 = self.import_scan_with_params(self.generic_sample_with_tags_filename, scan_type="Generic Findings Import")
299+
test_id = import0["test"]
300+
response = self.get_test_findings_api(test_id)
301+
findings = response["results"]
302+
# Make sure we have what we are looking for
303+
assert_tags_in_findings(findings, 2, ["security", "network"])
304+
# Reimport with a different report that has more tags
305+
self.reimport_scan_with_params(test_id, self.generic_sample_with_more_tags_filename, scan_type="Generic Findings Import")
306+
response = self.get_test_findings_api(test_id)
307+
findings = response["results"]
308+
# Make sure we have what we are looking for
309+
assert_tags_in_findings(findings, 2, ["security", "network", "hardened"])
310+
288311

289312
class InheritedTagsTests(DojoAPITestCase):
290313
fixtures = ["dojo_testdata.json"]

0 commit comments

Comments
 (0)