Skip to content

Commit 824ca50

Browse files
Merge branch 'bugfix' into github-secret-detection-report-parser
2 parents 5f7a7f1 + 13253f5 commit 824ca50

8 files changed

Lines changed: 7832 additions & 55 deletions

File tree

components/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "defectdojo",
3-
"version": "2.50.4",
3+
"version": "2.51.0-dev",
44
"license" : "BSD-3-Clause",
55
"private": true,
66
"dependencies": {

dojo/templates/dojo/findings_list_snippet.html

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,10 @@ <h3 class="has-filters">
399399
{% trans "Service" %}
400400
</th>
401401
<th scope="col">
402-
{% trans "Planned Remediation" %}
402+
{% trans "Planned Remediation Date" %}
403+
</th>
404+
<th scope="col">
405+
{% trans "Planned Remediation Version" %}
403406
</th>
404407
{% if filter_name != 'Closed' %}
405408
<th scope="col">
@@ -730,6 +733,9 @@ <h3 class="has-filters">
730733
<td class="nowrap">
731734
{% if finding.planned_remediation_date %}{{ finding.planned_remediation_date }}{% endif %}
732735
</td>
736+
<td class="nowrap">
737+
{% if finding.planned_remediation_version %}{{ finding.planned_remediation_version }}{% endif %}
738+
</td>
733739
{% if filter_name != 'Closed' %}
734740
<td class="nowrap">
735741
{% if finding.reviewers %}
@@ -828,6 +834,7 @@ <h3 class="has-filters">
828834
{% endif %}
829835
{ "data": "service" },
830836
{ "data": "planned_remediation_date" },
837+
{ "data": "planned_remediation_version" },
831838
{% if filter_name != 'Closed' %}
832839
{ "data": "reviewers" },
833840
{% endif %}

dojo/tools/kiuwan_sca/parser.py

Lines changed: 57 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import hashlib
22
import json
3+
import logging
34

45
from dojo.models import Finding
56

7+
logger = logging.getLogger(__name__)
8+
69
__author__ = "mwager"
710

811

@@ -37,50 +40,59 @@ def get_findings(self, filename, test):
3740
if row["muted"] is True:
3841
continue
3942

40-
finding = Finding(test=test)
41-
finding.unique_id_from_tool = row["id"]
42-
finding.cve = row["cve"]
43-
finding.description = row["description"]
44-
finding.severity = self.SEVERITY[row["securityRisk"]]
45-
46-
if "components" in row and len(row["components"]) > 0:
47-
finding.component_name = row["components"][0]["artifact"]
48-
finding.component_version = row["components"][0]["version"]
49-
finding.title = finding.component_name + " v" + str(finding.component_version)
50-
51-
if not finding.title:
52-
finding.title = row["cve"]
53-
54-
if "cwe" in row and "CWE-" in row["cwe"]:
55-
finding.cwe = int(row["cwe"].replace("CWE-", ""))
56-
57-
if "epss_score" in row:
58-
finding.epss_score = row["epss_score"]
59-
if "epss_percentile" in row:
60-
finding.epss_percentile = row["epss_percentile"]
61-
62-
if "cVSSv3BaseScore" in row:
63-
finding.cvssv3_score = float(row["cVSSv3BaseScore"])
64-
65-
finding.references = "See Kiuwan Web UI"
66-
finding.mitigation = "See Kiuwan Web UI"
67-
finding.static_finding = True
68-
69-
key = hashlib.sha256(
70-
(
71-
finding.description
72-
+ "|"
73-
+ finding.severity
74-
+ "|"
75-
+ finding.component_name
76-
+ "|"
77-
+ finding.component_version
78-
+ "|"
79-
+ str(finding.cwe)
80-
).encode("utf-8"),
81-
).hexdigest()
82-
83-
if key not in dupes:
84-
dupes[key] = finding
43+
components = row.get("components", [])
44+
if not components:
45+
logger.debug("Insights Finding from Kiuwan does not have a related component - Skipping.")
46+
continue
47+
48+
# We want one unique finding in DD for each component affected:
49+
for component in components:
50+
finding = Finding(test=test)
51+
finding.vuln_id_from_tool = str(row["id"])
52+
finding.cve = row["cve"]
53+
finding.description = row["description"]
54+
finding.severity = self.SEVERITY[row["securityRisk"]]
55+
56+
if "artifact" in component:
57+
finding.component_name = component["artifact"]
58+
if "version" in component:
59+
finding.component_version = component["version"]
60+
61+
if finding.component_name and finding.component_version:
62+
finding.title = f"{finding.component_name} v{finding.component_version}"
63+
else:
64+
finding.title = finding.cve or "Unnamed Finding"
65+
66+
if "cwe" in row and "CWE-" in row["cwe"]:
67+
finding.cwe = int(row["cwe"].replace("CWE-", ""))
68+
69+
if "epss_score" in row:
70+
finding.epss_score = row["epss_score"]
71+
if "epss_percentile" in row:
72+
finding.epss_percentile = row["epss_percentile"]
73+
74+
if "cVSSv3BaseScore" in row:
75+
finding.cvssv3_score = float(row["cVSSv3BaseScore"])
76+
77+
finding.references = "See Kiuwan Web UI"
78+
finding.mitigation = "See Kiuwan Web UI"
79+
finding.static_finding = True
80+
81+
key = hashlib.sha256(
82+
(
83+
finding.description
84+
+ "|"
85+
+ finding.severity
86+
+ "|"
87+
+ finding.component_name
88+
+ "|"
89+
+ finding.component_version
90+
+ "|"
91+
+ str(finding.cwe or "")
92+
).encode("utf-8"),
93+
).hexdigest()
94+
95+
if key not in dupes:
96+
dupes[key] = finding
8597

8698
return list(dupes.values())

dojo/tools/tenable/xml_format.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,11 @@ def get_findings(self, filename: str, test: Test) -> list:
239239
cwe_element_text = self.safely_get_element_text(
240240
item.find("cwe"),
241241
)
242+
242243
if cwe_element_text is not None:
243-
cwe = cwe_element_text
244+
match = re.search(r"\d+", cwe_element_text)
245+
if match:
246+
cwe = int(match.group())
244247

245248
# parsing and storing the CWE would affect dedupe/hash_codes, commentint out for now
246249
# if not cwe:

helm/defectdojo/Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
apiVersion: v2
2-
appVersion: "2.50.4"
2+
appVersion: "2.51.0-dev"
33
description: A Helm chart for Kubernetes to install DefectDojo
44
name: defectdojo
5-
version: 1.6.209
5+
version: 1.6.210-dev
66
icon: https://www.defectdojo.org/img/favicon.ico
77
maintainers:
88
- name: madchap

unittests/scans/tenable/nessus/nessus_with_cwe-.nessus

Lines changed: 7745 additions & 0 deletions
Large diffs are not rendered by default.

unittests/tools/test_kiuwan_sca_parser.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ def test_parse_file_with_two_vuln_has_two_findings(self):
1515
with (get_unit_tests_scans_path("kiuwan_sca") / "kiuwan_sca_two_vuln.json").open(encoding="utf-8") as testfile:
1616
parser = KiuwanSCAParser()
1717
findings = parser.get_findings(testfile, Test())
18-
# file contains 3, but we only get 2 as "muted" ones are ignored:
19-
self.assertEqual(2, len(findings))
18+
# file contains 3 cves, one of them is muted. so we have 2 cves with a total of 5 components
19+
self.assertEqual(5, len(findings))
2020

2121
def test_parse_file_with_multiple_vuln_has_multiple_finding(self):
2222
with (get_unit_tests_scans_path("kiuwan_sca") / "kiuwan_sca_many_vuln.json").open(encoding="utf-8") as testfile:
2323
parser = KiuwanSCAParser()
2424
findings = parser.get_findings(testfile, Test())
25-
# also tests deduplication as there are 28 findings in the file:
26-
self.assertEqual(27, len(findings))
25+
# also tests deduplication as there are 28 cves in the file (but some including >1 components!):
26+
self.assertEqual(45, len(findings))
2727

2828
def test_correct_mapping(self):
2929
with (get_unit_tests_scans_path("kiuwan_sca") / "kiuwan_sca_two_vuln.json").open(encoding="utf-8") as testfile:
@@ -37,7 +37,7 @@ def test_correct_mapping(self):
3737
self.assertEqual(finding1.component_name, "org.apache.cxf:cxf-rt-ws-policy")
3838
self.assertEqual(finding1.component_version, "3.3.5")
3939
self.assertEqual(finding1.cwe, 835)
40-
self.assertEqual(finding1.unique_id_from_tool, 158713)
40+
self.assertEqual(finding1.vuln_id_from_tool, "158713")
4141
self.assertEqual(finding1.cvssv3_score, 7.5)
4242
self.assertEqual(finding1.epss_score, 0.1)
4343
self.assertEqual(finding1.epss_percentile, 0.2)

unittests/tools/test_tenable_parser.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,16 @@ def test_parse_some_findings_with_cvssv3_nessus_legacy(self):
195195
self.assertEqual("http", endpoint.protocol)
196196
self.assertEqual("CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N", finding.cvssv3)
197197

198+
def test_parse_some_findings_with_nessus_with_cwe(self):
199+
with (get_unit_tests_scans_path("tenable/nessus") / "nessus_with_cwe-.nessus").open(encoding="utf-8") as testfile:
200+
parser = TenableParser()
201+
findings = parser.get_findings(testfile, self.create_test())
202+
for finding in findings:
203+
for endpoint in finding.unsaved_endpoints:
204+
endpoint.clean()
205+
finding = findings[0]
206+
self.assertEqual(94, finding.cwe)
207+
198208
def test_parse_many_findings_xml_nessus_was_legacy(self):
199209
with (get_unit_tests_scans_path("tenable/nessus_was") / "nessus_was_many_vuln.xml").open(encoding="utf-8") as testfile:
200210
parser = TenableParser()

0 commit comments

Comments
 (0)