From 4f3a8e2542e1f27a5d4c75e5c03e7f2a7af39a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20St=C3=A1rek?= Date: Thu, 7 Nov 2019 10:21:27 +0100 Subject: [PATCH] Implemented, tested --- README.md | 1 + config_example.json | 1 + fuzzer/src/configuration_manager.py | 4 ++++ fuzzer/src/request_build_helper.py | 3 +++ .../src/unit_tests/request_build_helper_tests.py | 14 ++++++++++++++ 5 files changed, 23 insertions(+) diff --git a/README.md b/README.md index c9d63cb..308651f 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ In config file you are able to specify following options: - **http_fuzzing** -> boolean value for enabling / disabling fuzzing of HTTP protocol - **skipping_endpoints_keywords** [list of string keywords] -> endpoints containing any keyword in it from this list will be skipped (can be used for skipping auth/logout endpoints) - **startup_command** -> startup command for your tested process / service, see more details in `procmon/README.md` +- **are_non_required_attributes_in_requests** -> boolean value, set to true, if you want attributes, that are specified as non-required, be part of URI part of request - **payloads_to_json_primitives_mapping** -> mapping of payloads folders to JSON primitives (see `config_example.json` for an example) - **boolean** -> array of folder names with payloads which will be used for JSON boolean primitive fuzzing - **number** -> array of folder names with payloads which will be used for JSON number primitive fuzzing diff --git a/config_example.json b/config_example.json index 599eacc..1f9cc1a 100644 --- a/config_example.json +++ b/config_example.json @@ -12,6 +12,7 @@ "skipping_endpoints_keywords": ["logout", "auth"], "receive_timeout": 2, "startup_command": ["python", "C:\\server\\httpd.py"], + "are_non_required_attributes_in_requests": true, "target": { "hostname": "target_hostname", "port": 3000, diff --git a/fuzzer/src/configuration_manager.py b/fuzzer/src/configuration_manager.py index 1944be5..59943a3 100644 --- a/fuzzer/src/configuration_manager.py +++ b/fuzzer/src/configuration_manager.py @@ -38,6 +38,10 @@ class ConfigurationManager: def _get_payloads_to_json_primitives_mapping(): return ConfigurationManager.config["payloads_to_json_primitives_mapping"] if "payloads_to_json_primitives_mapping" in ConfigurationManager.config else None + @staticmethod + def are_non_required_attributes_in_requests(): + return ConfigurationManager.config["are_non_required_attributes_in_requests"] if "are_non_required_attributes_in_requests" in ConfigurationManager.config else True + @staticmethod def get_receive_timeout(): return ConfigurationManager.config["receive_timeout"] diff --git a/fuzzer/src/request_build_helper.py b/fuzzer/src/request_build_helper.py index 876f673..9c7336c 100644 --- a/fuzzer/src/request_build_helper.py +++ b/fuzzer/src/request_build_helper.py @@ -58,9 +58,12 @@ class RequestBuildHelper(object): @staticmethod def _generate_additional_query_parameters(uri_parameters, already_used_parameters, id_generator, fuzzable): + are_non_required_attributes_in_requests = ConfigurationManager.are_non_required_attributes_in_requests() for uri_parameter in uri_parameters: parameter_name = uri_parameter["Name"] if parameter_name not in already_used_parameters and uri_parameter["Location"] == "Query": + if uri_parameter["Required"] is False and are_non_required_attributes_in_requests is False: + break prefix = "?" if "?" not in s_render().decode('ascii', 'ignore') else "&" name = "URI attribute, default value: " + parameter_name + ", id: " + next(id_generator) s_http_string(prefix + parameter_name + "=", fuzzable=False, encoding=EncodingTypes.ascii, name=name) diff --git a/fuzzer/src/unit_tests/request_build_helper_tests.py b/fuzzer/src/unit_tests/request_build_helper_tests.py index 5237684..adef75b 100644 --- a/fuzzer/src/unit_tests/request_build_helper_tests.py +++ b/fuzzer/src/unit_tests/request_build_helper_tests.py @@ -68,6 +68,20 @@ class RequestBuilderHelperTests(unittest.TestCase): uri = s_render().decode('utf8', 'ignore') self.assertEqual('/api/endpoint?id=1&attr=2', uri) + def test_generate_uri_single_non_required_query_parameter_is_not_in_uri(self): + ConfigurationManager.config = { + "are_non_required_attributes_in_requests": False + } + + uri_parameters = [ + {'Name': 'id', 'Required': False, 'ExampleValue': '1', 'Type': 'string', 'Format': None, 'Location': 'Query'}, + ] + + RequestBuildHelper.generate_uri('/api/endpoint', uri_parameters) + + uri = s_render().decode('utf8', 'ignore') + self.assertEqual('/api/endpoint', uri) + def test_generate_uri_combined_parameters(self): ConfigurationManager.config = { "fixed_url_attributes": {