From c4d1e083d5dc7965b963fe2b8cbe64c08c7acf91 Mon Sep 17 00:00:00 2001 From: devloop Date: Sun, 22 Sep 2024 10:59:14 +0200 Subject: [PATCH] reformat some code --- .../assertions/smart_checker.py | 40 ++-- .../assertions/smart_checker.py | 19 +- .../test_mod_sql/assertions/smart_checker.py | 19 +- .../test_mod_ssrf/assertions/smart_checker.py | 36 ++-- .../test_mod_xxe/assertions/smart_checker.py | 18 +- tests/integration/wapiti/misc_functions.py | 13 +- tests/integration/wapiti/test.py | 24 ++- tests/parsers/test_html_parser.py | 3 + tests/parsers/test_swagger_parser.py | 189 ++++++++++-------- tests/wappalyzer/test_wappalyzer.py | 3 + tests/web/test_crawl.py | 2 +- 11 files changed, 199 insertions(+), 167 deletions(-) diff --git a/tests/integration/test_mod_log4shell/assertions/smart_checker.py b/tests/integration/test_mod_log4shell/assertions/smart_checker.py index 2557bd7d3..dbe4c04de 100644 --- a/tests/integration/test_mod_log4shell/assertions/smart_checker.py +++ b/tests/integration/test_mod_log4shell/assertions/smart_checker.py @@ -1,6 +1,6 @@ #!/bin/python3 import re -import sys +import sys import json # This python script will check reports with urls in it @@ -9,21 +9,20 @@ # similar needs KEY_NOT_FOUND_STR = "Key {key} doesn't exist in the report" -CONTENT_MISTMATCH_STR= "Content {content_report} mismatch with the assertion {content_assertion}" +CONTENT_MISTMATCH_STR = "Content {content_report} mismatch with the assertion {content_assertion}" RAND_URL_PART = re.compile(r"(/[0-9a-z]+){4}-") -JSESSIONID_REG=re.compile(r"JSESSIONID=[0-9A-z]{32}") -PAYLOAD_REG=re.compile(r"jndi.*\.l") +JSESSIONID_REG = re.compile(r"JSESSIONID=[0-9A-z]{32}") +PAYLOAD_REG = re.compile(r"jndi.*\.l") - -def match_trim(string_1: str, string_2: str, reg: str)-> tuple[str,str]: +def match_trim(string_1: str, string_2: str, reg: str) -> tuple[str, str]: # Find the first match of the regex in both string, ensure that they # are at the same positions, and remove them, regexes MUST exist in the string # and MUST be at the same position assert (match_1 := reg.search(string_1)) and (match_2 := reg.search(string_2)), \ - "Regex: no match found" - return string_1[:match_1.start()]+string_1[match_1.end():],\ - string_2[:match_2.start()]+string_2[match_2.end():] + "Regex: no match found" + return string_1[:match_1.start()] + string_1[match_1.end():], \ + string_2[:match_2.start()] + string_2[match_2.end():] def static_checking(report, assertion): @@ -37,7 +36,8 @@ def static_checking(report, assertion): static_checking(item_report, item_assertion) else: assert report == assertion, \ - CONTENT_MISTMATCH_STR.format(content_report=report, content_assertion=assertion) + CONTENT_MISTMATCH_STR.format(content_report=report, content_assertion=assertion) + def main(): assert len(sys.argv) == 3, "wrong number of arguments" @@ -50,22 +50,22 @@ def main(): static_checking(json_report, json_assertion) - #"http_requrest" contain some non-static data - infos={ - "assertion":json_assertion["vulnerabilities"]["Log4Shell"][0]["http_request"], + # "http_requrest" contain some non-static data + infos = { + "assertion": json_assertion["vulnerabilities"]["Log4Shell"][0]["http_request"], "report": json_report["vulnerabilities"]["Log4Shell"][0]["http_request"] } if JSESSIONID_REG.search(infos["report"]) is not None: - infos["assertion"], infos["report"] = match_trim(infos["assertion"], - infos["report"], - JSESSIONID_REG) - infos["assertion"], infos["report"] = match_trim(infos["assertion"], - infos["report"], - PAYLOAD_REG) - + infos["assertion"], infos["report"] = match_trim(infos["assertion"], + infos["report"], + JSESSIONID_REG) + infos["assertion"], infos["report"] = match_trim(infos["assertion"], + infos["report"], + PAYLOAD_REG) return 0 + if __name__ == "__main__": sys.exit(main()) diff --git a/tests/integration/test_mod_permanentxss/assertions/smart_checker.py b/tests/integration/test_mod_permanentxss/assertions/smart_checker.py index f19082357..bde503fd5 100644 --- a/tests/integration/test_mod_permanentxss/assertions/smart_checker.py +++ b/tests/integration/test_mod_permanentxss/assertions/smart_checker.py @@ -1,6 +1,6 @@ #!/bin/python3 import re -import sys +import sys import json # This python script will check reports with urls in it @@ -9,24 +9,23 @@ # similar needs KEY_NOT_FOUND_STR = "Key {key} doesn't exist in the report" -CONTENT_MISTMATCH_STR= "CONTENT:\n\n{content_report} \n\nMISMATCH WITH THE ASSERTION:\n\n {content_assertion}" +CONTENT_MISTMATCH_STR = "CONTENT:\n\n{content_report} \n\nMISMATCH WITH THE ASSERTION:\n\n {content_assertion}" RAND_PAYLOAD_PART = re.compile(r"%28.*%29") - -def match_trim(string_1: str, string_2: str, reg: str)-> tuple[str,str]: +def match_trim(string_1: str, string_2: str, reg: str) -> tuple[str, str]: # Find the first match of the regex in both string, ensure that they # are at the same positions, and remove them, regexes MUST exist in the string # and MUST be at the same position assert (match_1 := reg.search(string_1)) and (match_2 := reg.search(string_2)), \ - "Regex: no match found" - return string_1[:match_1.start()]+string_1[match_1.end():],\ - string_2[:match_2.start()]+string_2[match_2.end():] + "Regex: no match found" + return string_1[:match_1.start()] + string_1[match_1.end():], \ + string_2[:match_2.start()] + string_2[match_2.end():] def static_checking(report, assertion, regex): if isinstance(report, dict) and isinstance(assertion, dict): - for key,_ in report.items(): + for key, _ in report.items(): assert key in assertion, KEY_NOT_FOUND_STR.format(key=key) if key == "http_request": report[key], assertion[key] = match_trim(report[key], assertion[key], regex) @@ -36,7 +35,8 @@ def static_checking(report, assertion, regex): static_checking(item_report, item_assertion, regex) else: assert report == assertion, \ - CONTENT_MISTMATCH_STR.format(content_report=report, content_assertion=assertion) + CONTENT_MISTMATCH_STR.format(content_report=report, content_assertion=assertion) + def main(): assert len(sys.argv) == 3, "wrong number of arguments" @@ -51,5 +51,6 @@ def main(): return 0 + if __name__ == "__main__": sys.exit(main()) diff --git a/tests/integration/test_mod_sql/assertions/smart_checker.py b/tests/integration/test_mod_sql/assertions/smart_checker.py index ef40cb00f..e4c30aa1c 100644 --- a/tests/integration/test_mod_sql/assertions/smart_checker.py +++ b/tests/integration/test_mod_sql/assertions/smart_checker.py @@ -1,6 +1,6 @@ #!/bin/python3 import re -import sys +import sys import json # This python script will check reports with urls in it @@ -9,24 +9,23 @@ # similar needs KEY_NOT_FOUND_STR = "Key {key} doesn't exist in the report" -CONTENT_MISTMATCH_STR= "CONTENT:\n\n{content_report} \n\nMISMATCH WITH THE ASSERTION:\n\n {content_assertion}" +CONTENT_MISTMATCH_STR = "CONTENT:\n\n{content_report} \n\nMISMATCH WITH THE ASSERTION:\n\n {content_assertion}" RAND_PAYLOAD_PART = re.compile(r"Linda[A-Z0-9%]*") - -def match_trim(string_1: str, string_2: str, reg: str)-> tuple[str,str]: +def match_trim(string_1: str, string_2: str, reg: str) -> tuple[str, str]: # Find the first match of the regex in both string, ensure that they # are at the same positions, and remove them, regexes MUST exist in the string # and MUST be at the same position assert (match_1 := reg.search(string_1)) and (match_2 := reg.search(string_2)), \ - "Regex: no match found" - return string_1[:match_1.start()]+string_1[match_1.end():],\ - string_2[:match_2.start()]+string_2[match_2.end():] + "Regex: no match found" + return string_1[:match_1.start()] + string_1[match_1.end():], \ + string_2[:match_2.start()] + string_2[match_2.end():] def static_checking(report, assertion, regex): if isinstance(report, dict) and isinstance(assertion, dict): - for key,_ in report.items(): + for key, _ in report.items(): assert key in assertion, KEY_NOT_FOUND_STR.format(key=key) if key == "http_request": report[key], assertion[key] = match_trim(report[key], assertion[key], regex) @@ -36,7 +35,8 @@ def static_checking(report, assertion, regex): static_checking(item_report, item_assertion, regex) else: assert report == assertion, \ - CONTENT_MISTMATCH_STR.format(content_report=report, content_assertion=assertion) + CONTENT_MISTMATCH_STR.format(content_report=report, content_assertion=assertion) + def main(): assert len(sys.argv) == 3, "wrong number of arguments" @@ -51,5 +51,6 @@ def main(): return 0 + if __name__ == "__main__": sys.exit(main()) diff --git a/tests/integration/test_mod_ssrf/assertions/smart_checker.py b/tests/integration/test_mod_ssrf/assertions/smart_checker.py index f3cd96ecb..d13ca539f 100644 --- a/tests/integration/test_mod_ssrf/assertions/smart_checker.py +++ b/tests/integration/test_mod_ssrf/assertions/smart_checker.py @@ -1,6 +1,6 @@ #!/bin/python3 import re -import sys +import sys import json # This python script will check reports with different dates, IP and random numbers in it @@ -10,20 +10,20 @@ ALL_KEYS = {"method", "path", "info", "level", "parameter", "wstg", "http_request"} KEY_NOT_FOUND_STR = "Key {key} doesn't exist in the report" -CONTENT_MISTMATCH_STR= "Content {content_report} mismatch with the assertion {content_assertion}" +CONTENT_MISTMATCH_STR = "Content {content_report} mismatch with the assertion {content_assertion}" DATE_REG = re.compile(r"[0-9]{4}(-[0-9]{2}){2}T([0-9]{2}:){2}[0-9]{2}\+[0-9]{2}:[0-9]{2}") IP_REG = re.compile(r"([0-9]{1,3}\.){3}[0-9]{1,3}") RAND_URL_PART = re.compile(r"(/[0-9a-z]+){4}-") -def match_trim(string_1: str, string_2: str, reg: str)-> tuple[str,str]: +def match_trim(string_1: str, string_2: str, reg: str) -> tuple[str, str]: # Find the first match of the regex in both string, ensure that they # are at the same positions, and remove them, regexes MUST exist in the string # and MUST be at the same position assert (match_1 := reg.search(string_1)) and (match_2 := reg.search(string_2)), \ - "Regex: no match found" - return string_1[:match_1.start()]+string_1[match_1.end():],\ - string_2[:match_2.start()]+string_2[match_2.end():] + "Regex: no match found" + return string_1[:match_1.start()] + string_1[match_1.end():], \ + string_2[:match_2.start()] + string_2[match_2.end():] def static_structure_checking(report: dict): @@ -33,12 +33,13 @@ def static_structure_checking(report: dict): for key in ALL_KEYS: assert key in report["vulnerabilities"]["Server Side Request Forgery"][0], KEY_NOT_FOUND_STR.format(key=key) + def static_content_checking(report, assertions): - for key in ALL_KEYS-{"info"}: + for key in ALL_KEYS - {"info"}: content_report = report["vulnerabilities"]["Server Side Request Forgery"][0][key] - content_assertion = assertions["vulnerabilities"]["Server Side Request Forgery"][0][key] - assert content_report == \ - content_assertion, \ + content_assertion = assertions["vulnerabilities"]["Server Side Request Forgery"][0][key] + assert content_report == \ + content_assertion, \ CONTENT_MISTMATCH_STR.format(content_report=content_report, content_assertion=content_assertion) @@ -54,21 +55,22 @@ def main(): static_structure_checking(json_report) static_content_checking(json_report, json_assertion) - #"info" contain some non-static data - infos={ - "assertion":json_assertion["vulnerabilities"]["Server Side Request Forgery"][0]["info"], + # "info" contain some non-static data + infos = { + "assertion": json_assertion["vulnerabilities"]["Server Side Request Forgery"][0]["info"], "report": json_report["vulnerabilities"]["Server Side Request Forgery"][0]["info"] } - #there are 2 times the IP address + # there are 2 times the IP address seq = [DATE_REG, IP_REG, IP_REG, RAND_URL_PART] for reg in seq: - infos["assertion"], infos["report"] = match_trim(infos["assertion"], - infos["report"], - reg) + infos["assertion"], infos["report"] = match_trim(infos["assertion"], + infos["report"], + reg) assert infos["assertion"] == infos["report"] return 0 + if __name__ == "__main__": sys.exit(main()) diff --git a/tests/integration/test_mod_xxe/assertions/smart_checker.py b/tests/integration/test_mod_xxe/assertions/smart_checker.py index ecc542a2f..88961ef4f 100644 --- a/tests/integration/test_mod_xxe/assertions/smart_checker.py +++ b/tests/integration/test_mod_xxe/assertions/smart_checker.py @@ -1,6 +1,6 @@ #!/bin/python3 import re -import sys +import sys import json # This python script will check reports with urls in it @@ -9,25 +9,25 @@ # similar needs KEY_NOT_FOUND_STR = "Key {key} doesn't exist in the report" -CONTENT_MISTMATCH_STR= "CONTENT:\n\n{content_report} \n\nMISMATCH WITH THE ASSERTION:\n\n {content_assertion}" +CONTENT_MISTMATCH_STR = "CONTENT:\n\n{content_report} \n\nMISMATCH WITH THE ASSERTION:\n\n {content_assertion}" RAND_URL_PART = re.compile(r"endpoint(/[0-9a-zA-Z_]*){5}") DATE_REG = re.compile(r"[0-9]{4}(-[0-9]{2}){2}T([0-9]{2}:){2}[0-9]{2}\+[0-9]{2}:[0-9]{2}") IP_REG = re.compile(r"([0-9]{1,3}\.){3}[0-9]{1,3}") -def match_trim(string_1: str, string_2: str, reg)-> tuple[str,str]: +def match_trim(string_1: str, string_2: str, reg) -> tuple[str, str]: # Find the first match of the regex in both string, ensure that they # are at the same positions, and remove them, regexes MUST exist in the string # and MUST be at the same position assert (match_1 := reg.search(string_1)) and (match_2 := reg.search(string_2)), \ - "Regex: no match found" - return string_1[:match_1.start()]+string_1[match_1.end():],\ - string_2[:match_2.start()]+string_2[match_2.end():] + "Regex: no match found" + return string_1[:match_1.start()] + string_1[match_1.end():], \ + string_2[:match_2.start()] + string_2[match_2.end():] def static_checking(report, assertion): if isinstance(report, dict) and isinstance(assertion, dict): - for key,_ in report.items(): + for key, _ in report.items(): assert key in assertion, KEY_NOT_FOUND_STR.format(key=key) if key == "http_request" and "http://endpoint" in report[key]: report[key], assertion[key] = match_trim(report[key], assertion[key], RAND_URL_PART) @@ -40,7 +40,8 @@ def static_checking(report, assertion): static_checking(item_report, item_assertion) else: assert report == assertion, \ - CONTENT_MISTMATCH_STR.format(content_report=report, content_assertion=assertion) + CONTENT_MISTMATCH_STR.format(content_report=report, content_assertion=assertion) + def main(): assert len(sys.argv) == 3, "wrong number of arguments" @@ -55,5 +56,6 @@ def main(): return 0 + if __name__ == "__main__": sys.exit(main()) diff --git a/tests/integration/wapiti/misc_functions.py b/tests/integration/wapiti/misc_functions.py index 7861c20d3..cf2d71d9a 100644 --- a/tests/integration/wapiti/misc_functions.py +++ b/tests/integration/wapiti/misc_functions.py @@ -2,14 +2,12 @@ from re import findall, MULTILINE from json import dumps -from templates_and_data import TREE_CHECKER - def purge_irrelevant_data(data) -> None: """ - Look recursively for any pattern matching a 2 lenght sized list with - "date", "last-modified", "keep-alive" or "etag" in a dictionnary containing lists, - dictionnaries, and other non-collections structures. Removing them because those + Look recursively for any pattern matching a 2 length sized list with + "date", "last-modified", "keep-alive" or "etag" in a dictionary containing lists, + dictionaries, and other non-collections structures. Removing them because those datas can change from one test to another and aren't really relevant """ if isinstance(data, dict): @@ -30,8 +28,9 @@ def purge_irrelevant_data(data) -> None: def filter_data(data, filter): """ - Filter recursively data from report using a filter, is sensitive to report changes and don't check if the filter is correct - make sure to write filter correctly or reinforce this function + Filter recursively data from report using a filter, is sensitive to report changes and don't check + if the filter is correct. + Make sure to write filter correctly or reinforce this function """ # Another check, type based, also considering if filter and data order match assert (type(data) is type(filter)) or (type(data) is type(None)), \ diff --git a/tests/integration/wapiti/test.py b/tests/integration/wapiti/test.py index 11e809221..36c1bd865 100644 --- a/tests/integration/wapiti/test.py +++ b/tests/integration/wapiti/test.py @@ -17,7 +17,7 @@ integration_data = json.load(integration_file) wanted_modules = set(chain.from_iterable([test["modules"].split(",") for _, test in integration_data.items()])) - assert wanted_modules.issubset(EXISTING_MODULES), f"{wanted_modules-EXISTING_MODULES} modules not existing" + assert wanted_modules.issubset(EXISTING_MODULES), f"{wanted_modules - EXISTING_MODULES} modules not existing" # Adding on-the-fly uuid for each target for each test # and using quotes for empty modules @@ -48,7 +48,7 @@ iter_tests = cycle(integration_data.items()) total_targets = sum([len(test["targets"]) for _, test in integration_data.items()]) -# If any target recieve too many requests, it might not have +# If any target receive too many requests, it might not have # started well, this is another way to fill the set to break # the loop requests_counter = defaultdict(int) @@ -66,19 +66,22 @@ requests_counter[target['name']] += 1 try: requests.get(f"{target['name']}", verify=False) - json_output_path = f"/home/{key_test}/{re.sub(r'[/:]','_',re.sub(r'^https?://', '', target['name']))}.out" + json_output_path = f"/home/{key_test}/{re.sub(r'[/:]', '_', re.sub(r'^https?://', '', target['name']))}.out" # We define supplementary arguments globally and for each target: more_args = target.get('supplementary_argument', '') + \ - ('' if target.get("erase_global_supplementary", False) - else content_test.get('supplementary_argument', '')) + ('' if target.get("erase_global_supplementary", False) + else content_test.get('supplementary_argument', '')) # We then call wapiti on each target of each module, generating a detailed JSON report - os.system(f"wapiti -u {target['name']} -m {content_test['modules']} " - f"-f json -o {json_output_path} " - f"{more_args} " - f"--detailed-report 2 --flush-session --verbose 2 ") - # Now we reparse the JSON to get only useful tests informations: + os.system( + f"wapiti -u {target['name']} -m {content_test['modules']} " + f"-f json -o {json_output_path} " + f"{more_args} " + f"--detailed-report 2 --flush-session --verbose 2 " + ) + + # Now we reparse the JSON to get only useful tests information: with open(json_output_path, "r") as bloated_output_file: bloated_output_data = json.load(bloated_output_file) with open(json_output_path, "w") as output_file: @@ -112,6 +115,7 @@ # 0.5 seconds penalty in case of no response to avoid requests spamming and being # too fast at blacklisting targets sleep(0.5) + if requests_counter[target['name']] > MAX_REQ: sys.stdout.write( f"Target {target['name']} from test {key_test} takes too long to respond\nSkipping...\n") diff --git a/tests/parsers/test_html_parser.py b/tests/parsers/test_html_parser.py index ccfa3bcb7..e00f71264 100644 --- a/tests/parsers/test_html_parser.py +++ b/tests/parsers/test_html_parser.py @@ -228,16 +228,19 @@ def test_base_other_links(): assert page.html_redirections == ["http://perdu.com/blog/adblock.html"] + def test_logged_in_success(): with open("tests/data/logged_in.html") as data_body: page = Html(data_body.read(), "http://perdu.com/index.php") assert page.is_logged_in() + def test_logged_in_failed_implicit(): with open("tests/data/logged_in_failed_implicit.html") as data_body: page = Html(data_body.read(), "http://perdu.com/index.php") assert not page.is_logged_in() + def test_logged_in_failed_explicit(): with open("tests/data/logged_in_failed_explicit.html") as data_body: page = Html(data_body.read(), "http://perdu.com/index.php") diff --git a/tests/parsers/test_swagger_parser.py b/tests/parsers/test_swagger_parser.py index 1c1ff5440..e64cb9fb3 100644 --- a/tests/parsers/test_swagger_parser.py +++ b/tests/parsers/test_swagger_parser.py @@ -1,93 +1,101 @@ from wapitiCore.parsers.swagger import Swagger from wapitiCore.net import Request + def test_swagger_parser_as_url_json(): url = "http://petstore.swagger.io/v2/swagger.json" page = Swagger(url) - assert{ - "https://petstore.swagger.io/v2/pet", - "https://petstore.swagger.io/v2/pet/findByStatus?status=available", - "https://petstore.swagger.io/v2/pet/findByTags?tags=default", - "https://petstore.swagger.io/v2/pet/1337", - "https://petstore.swagger.io/v2/pet/1337/uploadImage", - "https://petstore.swagger.io/v2/store/inventory", - "https://petstore.swagger.io/v2/store/order", - "https://petstore.swagger.io/v2/store/order/1337", - "https://petstore.swagger.io/v2/user", - "https://petstore.swagger.io/v2/user/createWithArray", - "https://petstore.swagger.io/v2/user/createWithList", - "https://petstore.swagger.io/v2/user/logout", - "https://petstore.swagger.io/v2/user/default", - "https://petstore.swagger.io/v2/user/login?username=default&password=default" - } == {x.url for x in page.get_requests()} + assert { + "https://petstore.swagger.io/v2/pet", + "https://petstore.swagger.io/v2/pet/findByStatus?status=available", + "https://petstore.swagger.io/v2/pet/findByTags?tags=default", + "https://petstore.swagger.io/v2/pet/1337", + "https://petstore.swagger.io/v2/pet/1337/uploadImage", + "https://petstore.swagger.io/v2/store/inventory", + "https://petstore.swagger.io/v2/store/order", + "https://petstore.swagger.io/v2/store/order/1337", + "https://petstore.swagger.io/v2/user", + "https://petstore.swagger.io/v2/user/createWithArray", + "https://petstore.swagger.io/v2/user/createWithList", + "https://petstore.swagger.io/v2/user/logout", + "https://petstore.swagger.io/v2/user/default", + "https://petstore.swagger.io/v2/user/login?username=default&password=default" + } == {x.url for x in page.get_requests()} + def test_swagger_parser_as_url_yaml(): url = "http://petstore.swagger.io/v2/swagger.yaml" page = Swagger(url) - assert{ - "https://petstore.swagger.io/v2/pet", - "https://petstore.swagger.io/v2/pet/findByStatus?status=available", - "https://petstore.swagger.io/v2/pet/findByTags?tags=default", - "https://petstore.swagger.io/v2/pet/1337", - "https://petstore.swagger.io/v2/pet/1337/uploadImage", - "https://petstore.swagger.io/v2/store/inventory", - "https://petstore.swagger.io/v2/store/order", - "https://petstore.swagger.io/v2/store/order/1337", - "https://petstore.swagger.io/v2/user", - "https://petstore.swagger.io/v2/user/createWithArray", - "https://petstore.swagger.io/v2/user/createWithList", - "https://petstore.swagger.io/v2/user/logout", - "https://petstore.swagger.io/v2/user/default", - "https://petstore.swagger.io/v2/user/login?username=default&password=default" - } == {x.url for x in page.get_requests()} + assert { + "https://petstore.swagger.io/v2/pet", + "https://petstore.swagger.io/v2/pet/findByStatus?status=available", + "https://petstore.swagger.io/v2/pet/findByTags?tags=default", + "https://petstore.swagger.io/v2/pet/1337", + "https://petstore.swagger.io/v2/pet/1337/uploadImage", + "https://petstore.swagger.io/v2/store/inventory", + "https://petstore.swagger.io/v2/store/order", + "https://petstore.swagger.io/v2/store/order/1337", + "https://petstore.swagger.io/v2/user", + "https://petstore.swagger.io/v2/user/createWithArray", + "https://petstore.swagger.io/v2/user/createWithList", + "https://petstore.swagger.io/v2/user/logout", + "https://petstore.swagger.io/v2/user/default", + "https://petstore.swagger.io/v2/user/login?username=default&password=default" + } == {x.url for x in page.get_requests()} + def test_swagger_parser_as_file(): url = "tests/data/swagger.json" page = Swagger(url) - assert{ - "https://petstore.swagger.io/v2/pet", - "https://petstore.swagger.io/v2/pet/findByStatus?status=available", - "https://petstore.swagger.io/v2/pet/findByTags?tags=default", - "https://petstore.swagger.io/v2/pet/1337", - "https://petstore.swagger.io/v2/pet/1337/uploadImage", - "https://petstore.swagger.io/v2/store/inventory", - "https://petstore.swagger.io/v2/store/order", - "https://petstore.swagger.io/v2/store/order/1337", - "https://petstore.swagger.io/v2/user", - "https://petstore.swagger.io/v2/user/createWithArray", - "https://petstore.swagger.io/v2/user/createWithList", - "https://petstore.swagger.io/v2/user/logout", - "https://petstore.swagger.io/v2/user/default", - "https://petstore.swagger.io/v2/user/login?username=default&password=default", - 'https://petstore.swagger.io/v2/v1.0/default/flavors&belongsTo=default' - } == {x.url for x in page.get_requests()} + assert { + "https://petstore.swagger.io/v2/pet", + "https://petstore.swagger.io/v2/pet/findByStatus?status=available", + "https://petstore.swagger.io/v2/pet/findByTags?tags=default", + "https://petstore.swagger.io/v2/pet/1337", + "https://petstore.swagger.io/v2/pet/1337/uploadImage", + "https://petstore.swagger.io/v2/store/inventory", + "https://petstore.swagger.io/v2/store/order", + "https://petstore.swagger.io/v2/store/order/1337", + "https://petstore.swagger.io/v2/user", + "https://petstore.swagger.io/v2/user/createWithArray", + "https://petstore.swagger.io/v2/user/createWithList", + "https://petstore.swagger.io/v2/user/logout", + "https://petstore.swagger.io/v2/user/default", + "https://petstore.swagger.io/v2/user/login?username=default&password=default", + 'https://petstore.swagger.io/v2/v1.0/default/flavors&belongsTo=default' + } == {x.url for x in page.get_requests()} + def test_swagger_file_complexe(): url = "tests/data/complexe_swagger.json" page = Swagger(url) - request_header = Request("https://fakeSwagger.fr/api/v2.0/projects?project_name=default", "HEAD", post_params="", file_params=[]) + request_header = Request("https://fakeSwagger.fr/api/v2.0/projects?project_name=default", "HEAD", post_params="", + file_params=[]) request_header.set_headers({'X-Request-Id': 'default'}) - request_get = Request("https://fakeSwagger.fr/api/v2.0/labels/1337", "GET", post_params="", file_params=[]) + request_get = Request("https://fakeSwagger.fr/api/v2.0/labels/1337", "GET", post_params="", file_params=[]) request_get.set_headers({'X-Request-Id': 'default'}) params = '{"name": "default", "description": "default", "expires_at": "1337", "access": [{"resource": "default", "action": "default", "effect": "default"}]}' - request_post = Request("https://fakeSwagger.fr/api/v2.0/projects/default/robots", "POST", post_params=params, file_params=[], enctype="application/json") + request_post = Request("https://fakeSwagger.fr/api/v2.0/projects/default/robots", "POST", post_params=params, + file_params=[], enctype="application/json") request_post.set_headers({'X-Request-Id': 'default'}) request_delete = Request("https://fakeSwagger.fr/api/v2.0/users/1337", "DELETE", post_params="", file_params=[]) request_delete.set_headers({'X-Request-Id': 'default'}) params = '{"id": "1337", "name": "default", "description": "default", "color": "default", "scope": "default", "project_id": "1337", "creation_time": "2024-08-16T16:03:08", "update_time": "2024-08-16T16:03:08"}' - request_put = Request("https://fakeSwagger.fr/api/v2.0/labels/1337", "PUT", post_params=params, file_params=[], enctype="application/json") + request_put = Request("https://fakeSwagger.fr/api/v2.0/labels/1337", "PUT", post_params=params, file_params=[], + enctype="application/json") request_put.set_headers({'X-Request-Id': 'default'}) params = '{"id": "1337", "vendor_type": "default", "vendor_id": "1337", "status": "default", "status_message": "default", "metrics": {"task_count": "1337", "success_task_count": "1337", "error_task_count": "1337", "pending_task_count": "1337", "running_task_count": "1337", "scheduled_task_count": "1337", "stopped_task_count": "1337"}, "trigger": "default", "extra_attrs": {}, "start_time": "default", "end_time": "default"}' - request_patch = Request("https://fakeSwagger.fr/api/v2.0/projects/default/preheat/policies/default/executions/1337", "PATCH", post_params=params, file_params=[], enctype="application/json") + request_patch = Request("https://fakeSwagger.fr/api/v2.0/projects/default/preheat/policies/default/executions/1337", + "PATCH", post_params=params, file_params=[], enctype="application/json") request_patch.set_headers({'X-Request-Id': 'default'}) list_request = [request_header, request_get, request_post, request_delete, request_put, request_patch] @@ -96,46 +104,53 @@ def test_swagger_file_complexe(): for item in list_request: assert item in requests + def test_swagger_file_yaml(): url = "tests/data/swagger.yaml" page = Swagger(url) - assert{ - "https://petstore.swagger.io/v2/pet", - "https://petstore.swagger.io/v2/pet/findByStatus?status=available", - "https://petstore.swagger.io/v2/pet/findByTags?tags=default", - "https://petstore.swagger.io/v2/pet/1337", - "https://petstore.swagger.io/v2/pet/1337/uploadImage", - "https://petstore.swagger.io/v2/store/inventory", - "https://petstore.swagger.io/v2/store/order", - "https://petstore.swagger.io/v2/store/order/1337", - "https://petstore.swagger.io/v2/user", - "https://petstore.swagger.io/v2/user/createWithArray", - "https://petstore.swagger.io/v2/user/createWithList", - "https://petstore.swagger.io/v2/user/logout", - "https://petstore.swagger.io/v2/user/default", - "https://petstore.swagger.io/v2/user/login?username=default&password=default" - } == {x.url for x in page.get_requests()} + assert { + "https://petstore.swagger.io/v2/pet", + "https://petstore.swagger.io/v2/pet/findByStatus?status=available", + "https://petstore.swagger.io/v2/pet/findByTags?tags=default", + "https://petstore.swagger.io/v2/pet/1337", + "https://petstore.swagger.io/v2/pet/1337/uploadImage", + "https://petstore.swagger.io/v2/store/inventory", + "https://petstore.swagger.io/v2/store/order", + "https://petstore.swagger.io/v2/store/order/1337", + "https://petstore.swagger.io/v2/user", + "https://petstore.swagger.io/v2/user/createWithArray", + "https://petstore.swagger.io/v2/user/createWithList", + "https://petstore.swagger.io/v2/user/logout", + "https://petstore.swagger.io/v2/user/default", + "https://petstore.swagger.io/v2/user/login?username=default&password=default" + } == {x.url for x in page.get_requests()} def test_openapi_file(): url = "tests/data/openapi.json" page = Swagger(base_url="https://fake.openapi.fr", swagger_url=url) - request_get = Request("https://fake.openapi.fr/v1/AdministrationSettings/GroupUsers", "GET", post_params="", file_params=[]) + request_get = Request("https://fake.openapi.fr/v1/AdministrationSettings/GroupUsers", "GET", post_params="", + file_params=[]) - request_post = Request("https://fake.openapi.fr/v1/AdministrationSettings/GroupUsers?userId=default", "POST", post_params="", file_params=[]) + request_post = Request("https://fake.openapi.fr/v1/AdministrationSettings/GroupUsers?userId=default", "POST", + post_params="", file_params=[]) - request_delete = Request("https://fake.openapi.fr/v1/AdministrationSettings/MailAccount?id=1337", "DELETE", post_params="", file_params=[]) + request_delete = Request("https://fake.openapi.fr/v1/AdministrationSettings/MailAccount?id=1337", "DELETE", + post_params="", file_params=[]) params = '{"alarmState": "default", "confirmingUserName": "default", "confirmingDateTime": "2024-08-16T16:03:08", "confirmingNote": "default"}' - request_put = Request("https://fake.openapi.fr/v1/Alarms/1337", "PUT", post_params=params, file_params=[], enctype= "application/json") + request_put = Request("https://fake.openapi.fr/v1/Alarms/1337", "PUT", post_params=params, file_params=[], + enctype="application/json") params = '{"active": true, "userName": "default", "emailAddress": "default", "role": "1337", "networksVisibility": true}' - request_put2 = Request("https://fake.openapi.fr/v1/AdministrationSettings/GroupUsers", "PUT", post_params=params, file_params=[], enctype= "application/json") + request_put2 = Request("https://fake.openapi.fr/v1/AdministrationSettings/GroupUsers", "PUT", post_params=params, + file_params=[], enctype="application/json") params = '{"active": true, "userName": "default", "emailAddress": "default", "role": "1337", "networksVisibility": true}' - request_patch = Request("https://fake.openapi.fr/v1/AdministrationSettings/GroupUsers", "PATCH", post_params=params, file_params=[], enctype= "application/json") + request_patch = Request("https://fake.openapi.fr/v1/AdministrationSettings/GroupUsers", "PATCH", post_params=params, + file_params=[], enctype="application/json") list_request = [request_get, request_post, request_delete, request_patch, request_put, request_put2] requests = page.get_requests() @@ -143,22 +158,24 @@ def test_openapi_file(): for item in list_request: assert item in requests + def test_openapi_yaml_file(): url = "tests/data/openapi.yaml" page = Swagger(base_url="https://fake.openapi.fr", swagger_url=url) - assert{ - "https://fake.openapi.fr/", - "https://fake.openapi.fr/eval?s=default", - "https://fake.openapi.fr/help" - } == {x.url for x in page.get_requests()} + assert { + "https://fake.openapi.fr/", + "https://fake.openapi.fr/eval?s=default", + "https://fake.openapi.fr/help" + } == {x.url for x in page.get_requests()} + def test_openapi3(): url = "tests/data/openapi3.yaml" page = Swagger(base_url="https://fake.openapi.fr", swagger_url=url) - assert{ - "https://fake.openapi.fr:8080/v1/pets?limit=1337", - "https://fake.openapi.fr:8080/v1/pets", - "https://fake.openapi.fr:8080/v1/pets/default" - } == {x.url for x in page.get_requests()} + assert { + "https://fake.openapi.fr:8080/v1/pets?limit=1337", + "https://fake.openapi.fr:8080/v1/pets", + "https://fake.openapi.fr:8080/v1/pets/default" + } == {x.url for x in page.get_requests()} diff --git a/tests/wappalyzer/test_wappalyzer.py b/tests/wappalyzer/test_wappalyzer.py index fa0d3c962..80f33f516 100644 --- a/tests/wappalyzer/test_wappalyzer.py +++ b/tests/wappalyzer/test_wappalyzer.py @@ -1,9 +1,11 @@ from typing import Dict from unittest import mock from unittest.mock import MagicMock, mock_open + import respx import httpx import pytest + from wapitiCore.wappalyzer.wappalyzer import ApplicationData, Wappalyzer from wapitiCore.net.response import Response @@ -101,6 +103,7 @@ def open_mock(filename, *args, **kwargs): if filename == expected_filename: return mock_open(read_data=content).return_value raise FileNotFoundError('(mock) Unable to open {filename}') + return MagicMock(side_effect=open_mock) files = { diff --git a/tests/web/test_crawl.py b/tests/web/test_crawl.py index 03fcd9c4f..f693d17dc 100644 --- a/tests/web/test_crawl.py +++ b/tests/web/test_crawl.py @@ -63,7 +63,7 @@ def process(http_request): remaining_requests = set([request async for request in wapiti.persister.get_to_browse()]) all_requests = set([request async for request, __ in wapiti.persister.get_links()]) # We stop giving new links at page > 20 but page 20 will give urls for 21 and 22 - # so we have 24 paginated pages (23 from 0 to 22) + root url here + # so, we have 24 paginated pages (23 from 0 to 22) + root url here assert len(all_requests) == 24 # We are done as we scanned all the pages assert not remaining_requests - all_requests