Skip to content

Commit c5f921d

Browse files
🎉 Implement Fortify Webinspect new report format (#12155)
* 🎉 Implement Fortify Webinspect new report format * update * fix * update * update * update * update * update * update according to comment * docs update * fix
1 parent bd59489 commit c5f921d

File tree

4 files changed

+2002
-1
lines changed

4 files changed

+2002
-1
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ If you import a .fpr file, the parser will look for the file 'audit.fvdl' and an
88
### Sample Scan Data
99
Sample Fortify scans can be found [here](https://github.com/DefectDojo/django-DefectDojo/tree/master/unittests/scans/fortify).
1010

11+
### Fortify Webinspect report formats.
12+
Fortify Webinspect released in version 24.2 a new xml report format. This parser is able to handle both report formats. See [this issue](https://github.com/DefectDojo/django-DefectDojo/issues/12065) for further information.
13+
1114
#### Generate XML Output from Foritfy
1215
This section describes how to import XML generated from a Fortify FPR. It assumes you
1316
already have, or know how to acquire, an FPR file. Once you have the FPR file you will need

dojo/tools/fortify/xml_parser.py

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,69 @@
11
from defusedxml import ElementTree
22

3-
from dojo.models import Finding
3+
from dojo.models import Endpoint, Finding
44

55

66
class FortifyXMLParser:
77
def parse_xml(self, filename, test):
88
fortify_scan = ElementTree.parse(filename)
99
root = fortify_scan.getroot()
10+
if root.tag == "Scan":
11+
return self.xml_structure_24_2(root, test)
12+
if root.tag == "ReportDefinition":
13+
return self.xml_structure_before_24_2(root, test)
14+
raise ValueError
15+
16+
def xml_structure_24_2(self, root, test):
17+
items = []
18+
for issues in root.findall("Issues"):
19+
for issue in issues.iter("Issue"):
20+
check_type_id = issue.find("CheckTypeID").text
21+
engine_type = issue.find("EngineType").text
22+
url = issue.find("URL").text
23+
scheme = issue.find("Scheme").text
24+
host = issue.find("Host").text
25+
port = issue.find("Port").text
26+
vulnerable_session = issue.find("VulnerableSession").text
27+
vulnerability_id = issue.find("VulnerabilityID").text
28+
severity = issue.find("Severity").text
29+
name = issue.find("Name").text
30+
raw_response = issue.find("RawResponse").text
31+
description = ""
32+
description += "**CheckTypeID:** " + check_type_id + "\n"
33+
description += "**URL:** " + url + "\n"
34+
description += "**EngineType:** " + engine_type + "\n"
35+
description += "**Scheme:** " + scheme + "\n"
36+
description += "**VulnerabilityID:** " + vulnerability_id + "\n"
37+
description += "**VulnerableSession:** " + vulnerable_session + "\n"
38+
finding = Finding(
39+
title=name,
40+
severity=self.severity_translator(severity=int(severity)),
41+
static_finding=True,
42+
test=test,
43+
description=description,
44+
)
45+
if raw_response is not None:
46+
finding.unsaved_req_resp = []
47+
finding.unsaved_req_resp.append({"req": "", "resp": str(raw_response)})
48+
if host is not None:
49+
finding.unsaved_endpoints = [Endpoint(host=host, port=port)]
50+
items.append(finding)
51+
return items
52+
53+
def severity_translator(self, severity):
54+
if severity == 0:
55+
return "Info"
56+
if severity == 1:
57+
return "Low"
58+
if severity == 2:
59+
return "Medium"
60+
if severity == 3:
61+
return "High"
62+
if severity == 4:
63+
return "Critical"
64+
return "Info"
65+
66+
def xml_structure_before_24_2(self, root, test):
1067
# Get Category Information:
1168
# Abstract, Explanation, Recommendation, Tips
1269
cat_meta = {}

0 commit comments

Comments
 (0)