Skip to content

Commit 72d0f3e

Browse files
Merge branch 'bugfix' into ibmapp_parserfixavailable
2 parents acb3e6e + cf2a8b1 commit 72d0f3e

10 files changed

Lines changed: 126 additions & 16 deletions

File tree

dojo/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
# Django starts so that shared_task will use this app.
55
from .celery import app as celery_app # noqa: F401
66

7-
__version__ = "2.52.0"
7+
__version__ = "2.52.1"
88
__url__ = "https://github.com/DefectDojo/django-DefectDojo"
99
__docs__ = "https://documentation.defectdojo.com"

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

dojo/tools/jfrog_xray_unified/parser.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ def get_item(vulnerability, test):
104104
else:
105105
title = vulnerability["summary"]
106106

107-
references = "\n".join(vulnerability["references"])
107+
references_str = vulnerability.get("references")
108+
references = "\n".join(references_str) if isinstance(references_str, list) else (references_str if isinstance(references_str, str) else "")
108109

109110
scan_time = datetime.strptime(
110111
vulnerability["artifact_scan_time"], "%Y-%m-%dT%H:%M:%S%z",
@@ -118,15 +119,18 @@ def get_item(vulnerability, test):
118119
# remove package type from component name
119120
component_name = component_name.split("://", 1)[1]
120121

121-
tags = ["packagetype_" + vulnerability["package_type"]]
122+
tags = []
123+
package_type = vulnerability.get("package_type")
124+
if package_type:
125+
tags.append("packagetype_" + package_type)
122126

123127
# create the finding object
124128
finding = Finding(
125129
title=title,
126130
test=test,
127131
severity=severity,
128132
description=(
129-
vulnerability["description"] + "\n\n" + extra_desc
133+
vulnerability.get("description", vulnerability.get("summary")) + "\n\n" + extra_desc
130134
).strip(),
131135
mitigation=mitigation,
132136
component_name=component_name,

helm/defectdojo/Chart.yaml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ apiVersion: v2
22
appVersion: "2.53.0-dev"
33
description: A Helm chart for Kubernetes to install DefectDojo
44
name: defectdojo
5-
version: 1.8.1-dev
5+
version: 1.8.2-dev
66
icon: https://defectdojo.com/hubfs/DefectDojo_favicon.png
77
maintainers:
88
- name: madchap
@@ -34,8 +34,4 @@ dependencies:
3434
# description: Critical bug
3535
annotations:
3636
artifacthub.io/prerelease: "true"
37-
artifacthub.io/changes: |
38-
- kind: fixed
39-
description: Broken rendering of media PVC
40-
- kind: fixed
41-
description: Typo in description of digests
37+
artifacthub.io/changes: ""

helm/defectdojo/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ kubectl delete pvc data-defectdojo-redis-0 data-defectdojo-postgresql-0
495495
496496
# General information about chart values
497497
498-
![Version: 1.8.1-dev](https://img.shields.io/badge/Version-1.8.1--dev-informational?style=flat-square) ![AppVersion: 2.53.0-dev](https://img.shields.io/badge/AppVersion-2.53.0--dev-informational?style=flat-square)
498+
![Version: 1.8.2-dev](https://img.shields.io/badge/Version-1.8.2--dev-informational?style=flat-square) ![AppVersion: 2.53.0-dev](https://img.shields.io/badge/AppVersion-2.53.0--dev-informational?style=flat-square)
499499
500500
A Helm chart for Kubernetes to install DefectDojo
501501
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+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"total_rows": 123,
3+
"rows": [
4+
{
5+
"cves": [
6+
{
7+
"cve": "CVE-2023-42282",
8+
"cvss_v3_score": 9.8,
9+
"cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
10+
}
11+
],
12+
"cvss3_max_score": 9.8,
13+
"severity": "Critical",
14+
"component_physical_path": "ip:2.0.0",
15+
"impact_path": [
16+
"somepath"
17+
],
18+
"fixed_versions": [
19+
"2.0.1",
20+
"1.1.9"
21+
],
22+
"issue_id": "XRAY-123",
23+
"project_keys": [
24+
"somepath"
25+
],
26+
"applicability": null,
27+
"applicability_result": "not_scanned",
28+
"summary": "The ip package before 1.1.9 for Node.js might allow SSRF because some IP addresses (such as 0x7f.1) are improperly categorized as globally routable via isPublic.",
29+
"vulnerable_component": "npm://ip:2.0.0",
30+
"impacted_artifact": "build://[some_artifact_id]",
31+
"path": "somepath",
32+
"published": "2024-02-09T16:30:10Z",
33+
"artifact_scan_time": "2025-11-03T11:42:09Z"
34+
}
35+
]
36+
}

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"]

unittests/tools/test_jfrog_xray_unified_parser.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,3 +345,12 @@ def test_parse_file_with_another_report(self):
345345
findings = parser.get_findings(testfile, Test())
346346
testfile.close()
347347
self.assertEqual(7, len(findings))
348+
349+
def test_parse_file_issue_13628(self):
350+
testfile = (get_unit_tests_scans_path("jfrog_xray_unified") / "issue_13628.json").open(encoding="utf-8")
351+
parser = JFrogXrayUnifiedParser()
352+
findings = parser.get_findings(testfile, Test())
353+
testfile.close()
354+
self.assertEqual(1, len(findings))
355+
self.assertEqual("Critical", findings[0].severity)
356+
self.assertEqual("XRAY-123 - The ip package before 1.1.9 for Node.js might allow SSRF because some IP addresses (such as 0x7f.1) are improperly categorized as globally routable via isPublic.", findings[0].title)

0 commit comments

Comments
 (0)