forked from DefectDojo/django-DefectDojo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser.py
125 lines (111 loc) · 4.42 KB
/
parser.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import hashlib
import re
import html2text
from defusedxml.ElementTree import parse
from dojo.models import Endpoint, Finding
class MicrofocusWebinspectParser(object):
"""Micro Focus Webinspect XML report parser"""
def get_scan_types(self):
return ["Microfocus Webinspect Scan"]
def get_label_for_scan_types(self, scan_type):
return scan_type
def get_description_for_scan_types(self, scan_type):
return "Import XML report"
def get_findings(self, file, test):
tree = parse(file)
# get root of tree.
root = tree.getroot()
if "Sessions" not in root.tag:
raise ValueError(
"This doesn't seem to be a valid Webinspect xml file."
)
dupes = dict()
for session in root:
url = session.find("URL").text
endpoint = Endpoint.from_uri(url)
issues = session.find("Issues")
for issue in issues.findall("Issue"):
mitigation = None
reference = None
severity = MicrofocusWebinspectParser.convert_severity(
issue.find("Severity").text
)
for content in issue.findall("ReportSection"):
name = content.find("Name").text
if "Summary" in name:
if content.find("SectionText").text:
description = content.find("SectionText").text
if "Fix" in name:
if content.find("SectionText").text:
mitigation = content.find("SectionText").text
if "Reference" in name:
if name and content.find("SectionText").text:
reference = html2text.html2text(
content.find("SectionText").text
)
cwe = 0
description = ""
classifications = issue.find("Classifications")
if classifications is not None:
for content in classifications.findall('Classification'):
# detect CWE number
# TODO support more than one CWE number
if "kind" in content.attrib and "CWE" == content.attrib["kind"]:
cwe = MicrofocusWebinspectParser.get_cwe(content.attrib['identifier'])
description += "\n\n" + content.text + "\n"
finding = Finding(
title=issue.findtext("Name"),
test=test,
cwe=cwe,
description=description,
mitigation=mitigation,
severity=severity,
references=reference,
static_finding=False,
dynamic_finding=True,
nb_occurences=1,
)
if "id" in issue.attrib:
finding.unique_id_from_tool = issue.attrib.get("id")
# manage endpoint
finding.unsaved_endpoints = [endpoint]
# make dupe hash key
dupe_key = hashlib.sha256(
"|".join(
[
finding.description,
finding.title,
finding.severity,
]
).encode("utf-8")
).hexdigest()
# check if dupes are present.
if dupe_key in dupes:
find = dupes[dupe_key]
find.unsaved_endpoints.extend(finding.unsaved_endpoints)
find.nb_occurences += finding.nb_occurences
else:
dupes[dupe_key] = finding
return list(dupes.values())
@staticmethod
def convert_severity(val):
if val == "0":
return "Info"
elif val == "1":
return "Low"
elif val == "2":
return "Medium"
elif val == "3":
return "High"
elif val == "4":
return "Critical"
else:
return "Info"
@staticmethod
def get_cwe(val):
# Match only the first CWE!
cweSearch = re.search("CWE-(\\d+)", val, re.IGNORECASE)
if cweSearch:
return int(cweSearch.group(1))
else:
return 0