Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions docs/content/en/integrations/parsers/file/wfuzz.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ The return code matching are directly put in Severity as follow(this is hardcode

HTTP Return Code | Severity
-----------------|---------
200 | High
302 | Low
401 | Medium
403 | Medium
404 | Medium
407 | Medium
500 | Low
missing | Low
200 - 299 | High
300 - 399 | Low
400 - 499 | Medium
>= 500 | Low

### Sample Scan Data
Sample Wfuzz JSON importer scans can be found [here](https://github.com/DefectDojo/django-DefectDojo/tree/master/unittests/scans/wfuzz).
33 changes: 17 additions & 16 deletions dojo/tools/wfuzz/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ class WFuzzParser(object):
A class that can be used to parse the WFuzz JSON report files
"""

# table to match HTTP error code and severity
SEVERITY = {
"200": "High",
"302": "Low",
"401": "Medium",
"403": "Medium",
"404": "Medium",
"407": "Medium",
"500": "Low"
}
# match HTTP error code and severity
def severity_mapper(self, input):
if 200 <= int(input) <= 299:
return "High"
elif 300 <= int(input) <= 399:
return "Low"
elif 400 <= int(input) <= 499:
return "Medium"
elif 500 <= int(input):
return "Low"

def get_scan_types(self):
return ["WFuzz JSON report"]
Expand All @@ -32,16 +32,17 @@ def get_description_for_scan_types(self, scan_type):

def get_findings(self, filename, test):
data = json.load(filename)

dupes = {}
for item in data:
url = hyperlink.parse(item["url"])
return_code = str(item["code"])
severity = self.SEVERITY[return_code]
return_code = item.get("code", None)
if return_code is None:
severity = "Low"
else:
severity = self.severity_mapper(input=return_code)
description = f"The URL {url.to_text()} must not be exposed\n Please review your configuration\n"

dupe_key = hashlib.sha256(
(url.to_text() + return_code).encode("utf-8")
(url.to_text() + str(return_code)).encode("utf-8")
).hexdigest()

if dupe_key in dupes:
Expand All @@ -68,7 +69,7 @@ def get_findings(self, filename, test):
)
]
finding.unsaved_req_resp = [
{"req": item["payload"], "resp": str(item["code"])}
{"req": item["payload"], "resp": str(return_code)}
]
dupes[dupe_key] = finding
return list(dupes.values())
13 changes: 13 additions & 0 deletions unittests/scans/wfuzz/one_finding_responsecode_missing.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[
{
"chars": 2823,
"payload": "/server-status | GET /server-status HTTP/1.1\nContent-Type: application/x-www-form-urlencoded\nUser-Agent: Wfuzz/3.1.0\nHost: example.com\n\n",
"lines": 0,
"location": "",
"method": "GET",
"post_data": [],
"server": "",
"url": "https://example.com/server-status",
"words": 60
}
]
9 changes: 9 additions & 0 deletions unittests/tools/test_wfuzz_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,12 @@ def test_issue_7863(self):
endpoint.clean()
self.assertEqual(1, len(findings))
self.assertEqual("Medium", findings[0].severity)

def test_one_finding_responsecode_missing(self):
testfile = open("unittests/scans/wfuzz/one_finding_responsecode_missing.json")
parser = WFuzzParser()
findings = parser.get_findings(testfile, Test())
for finding in findings:
for endpoint in finding.unsaved_endpoints:
endpoint.clean()
self.assertEqual(1, len(findings))