diff --git a/docs/content/en/integrations/parsers/file/wfuzz.md b/docs/content/en/integrations/parsers/file/wfuzz.md index 1893c359bd2..b76c7b186eb 100644 --- a/docs/content/en/integrations/parsers/file/wfuzz.md +++ b/docs/content/en/integrations/parsers/file/wfuzz.md @@ -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). \ No newline at end of file diff --git a/dojo/tools/wfuzz/parser.py b/dojo/tools/wfuzz/parser.py index a19cd869bd8..eb6b3186694 100644 --- a/dojo/tools/wfuzz/parser.py +++ b/dojo/tools/wfuzz/parser.py @@ -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"] @@ -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: @@ -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()) diff --git a/unittests/scans/wfuzz/one_finding_responsecode_missing.json b/unittests/scans/wfuzz/one_finding_responsecode_missing.json new file mode 100644 index 00000000000..ca120d9d17b --- /dev/null +++ b/unittests/scans/wfuzz/one_finding_responsecode_missing.json @@ -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 + } +] \ No newline at end of file diff --git a/unittests/tools/test_wfuzz_parser.py b/unittests/tools/test_wfuzz_parser.py index ef826921f9d..05eb69eebad 100644 --- a/unittests/tools/test_wfuzz_parser.py +++ b/unittests/tools/test_wfuzz_parser.py @@ -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))