From 3610037075fcb59d97074a4124e158fdecde0e27 Mon Sep 17 00:00:00 2001 From: Manuel Sommer Date: Wed, 7 Feb 2024 23:22:04 +0100 Subject: [PATCH 1/4] :bug: fix wfuzz 301, issue 6182 --- docs/content/en/integrations/parsers/file/wfuzz.md | 1 + dojo/tools/wfuzz/parser.py | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/content/en/integrations/parsers/file/wfuzz.md b/docs/content/en/integrations/parsers/file/wfuzz.md index 1893c359bd2..9284d4901a0 100644 --- a/docs/content/en/integrations/parsers/file/wfuzz.md +++ b/docs/content/en/integrations/parsers/file/wfuzz.md @@ -9,6 +9,7 @@ The return code matching are directly put in Severity as follow(this is hardcode HTTP Return Code | Severity -----------------|--------- 200 | High +301 | Low 302 | Low 401 | Medium 403 | Medium diff --git a/dojo/tools/wfuzz/parser.py b/dojo/tools/wfuzz/parser.py index a19cd869bd8..aa2d4483d5d 100644 --- a/dojo/tools/wfuzz/parser.py +++ b/dojo/tools/wfuzz/parser.py @@ -13,6 +13,7 @@ class WFuzzParser(object): # table to match HTTP error code and severity SEVERITY = { "200": "High", + "301": "Low", "302": "Low", "401": "Medium", "403": "Medium", From 3cc1c66b3e9085d40f455dbc11b253132c3b1734 Mon Sep 17 00:00:00 2001 From: Manuel Sommer Date: Thu, 8 Feb 2024 02:01:11 +0100 Subject: [PATCH 2/4] make severity mapper more robust --- .../en/integrations/parsers/file/wfuzz.md | 12 ++++------ dojo/tools/wfuzz/parser.py | 23 +++++++++---------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/docs/content/en/integrations/parsers/file/wfuzz.md b/docs/content/en/integrations/parsers/file/wfuzz.md index 9284d4901a0..22062dfdea6 100644 --- a/docs/content/en/integrations/parsers/file/wfuzz.md +++ b/docs/content/en/integrations/parsers/file/wfuzz.md @@ -8,14 +8,10 @@ The return code matching are directly put in Severity as follow(this is hardcode HTTP Return Code | Severity -----------------|--------- -200 | High -301 | Low -302 | Low -401 | Medium -403 | Medium -404 | Medium -407 | Medium -500 | 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 aa2d4483d5d..4dc5710f5ed 100644 --- a/dojo/tools/wfuzz/parser.py +++ b/dojo/tools/wfuzz/parser.py @@ -10,17 +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", - "301": "Low", - "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"] @@ -38,7 +37,7 @@ def get_findings(self, filename, test): for item in data: url = hyperlink.parse(item["url"]) return_code = str(item["code"]) - severity = self.SEVERITY[return_code] + 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( From 357774756dc27ea9d535c3ac67ac1fff0d0b6b7c Mon Sep 17 00:00:00 2001 From: Manuel Sommer Date: Thu, 8 Feb 2024 08:44:10 +0100 Subject: [PATCH 3/4] unittest for missing response code --- dojo/tools/wfuzz/parser.py | 13 +++++++------ .../wfuzz/one_finding_responsecode_missing.json | 13 +++++++++++++ unittests/tools/test_wfuzz_parser.py | 9 +++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 unittests/scans/wfuzz/one_finding_responsecode_missing.json diff --git a/dojo/tools/wfuzz/parser.py b/dojo/tools/wfuzz/parser.py index 4dc5710f5ed..eb6b3186694 100644 --- a/dojo/tools/wfuzz/parser.py +++ b/dojo/tools/wfuzz/parser.py @@ -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_mapper(input=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)) From 118918757053e1f9e38fe1065c1a06eaa96e2619 Mon Sep 17 00:00:00 2001 From: Manuel Sommer Date: Thu, 8 Feb 2024 08:46:11 +0100 Subject: [PATCH 4/4] update docs --- docs/content/en/integrations/parsers/file/wfuzz.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/content/en/integrations/parsers/file/wfuzz.md b/docs/content/en/integrations/parsers/file/wfuzz.md index 22062dfdea6..b76c7b186eb 100644 --- a/docs/content/en/integrations/parsers/file/wfuzz.md +++ b/docs/content/en/integrations/parsers/file/wfuzz.md @@ -8,6 +8,7 @@ The return code matching are directly put in Severity as follow(this is hardcode HTTP Return Code | Severity -----------------|--------- +missing | Low 200 - 299 | High 300 - 399 | Low 400 - 499 | Medium