def test_multiple_post_fuzz_hooks(mock_client, decorator_args, fuzzing_request_args): def post_fuzz_hook_a(operation, fuzzed_input): if '_request_options' not in fuzzed_input: fuzzed_input['_request_options'] = {} if 'headers' not in fuzzed_input['_request_options']: fuzzed_input['_request_options']['headers'] = {} fuzzed_input['_request_options']['headers']['__a__'] = 'a' def post_fuzz_hook_b(operation, fuzzed_input): if '_request_options' not in fuzzed_input: fuzzed_input['_request_options'] = {} if 'headers' not in fuzzed_input['_request_options']: fuzzed_input['_request_options']['headers'] = {} fuzzed_input['_request_options']['headers']['__b__'] = 'b' fuzz_lightyear.hooks.post_fuzz(**decorator_args)(post_fuzz_hook_a) fuzz_lightyear.hooks.post_fuzz(**decorator_args)(post_fuzz_hook_b) request = FuzzingRequest(**fuzzing_request_args) request.send() request_headers = request.fuzzed_input.get('_request_options', {}).get('headers', {}) assert request_headers['__a__'] == 'a' assert request_headers['__b__'] == 'b'
def test_json(mock_client): request = FuzzingRequest( operation_id='post_various_locations', tag='location', path_id='path', query='a', form='b', header='c', ) request.send() assert request.json() == { 'method': 'POST', 'path': '/location/path', 'query': { 'query': 'a', }, 'formData': { 'form': 'b', }, 'header': { 'header': 'c', }, } assert str(request) == (f'curl -X POST {URL}/location/path?query=a ' '--data \'form=b\' ' '-H \'header: c\' ' '-H \'Cookie: session=victim_session\'') assert repr(request) == 'FuzzingRequest(location.post_various_locations)'
def test_session_fixtures(mock_client): count = 0 def nested_function(): nonlocal count count += 1 return count def child_a(nested): return nested def child_b(nested): return nested def function(a, b): assert a == b return 'does_not_matter' fuzz_lightyear.register_factory('nested')(nested_function) fuzz_lightyear.register_factory('a')(child_a) fuzz_lightyear.register_factory('b')(child_b) fuzz_lightyear.register_factory('string')(function) request = FuzzingRequest( operation_id='get_expect_primitives', tag='types', ) request.send()
def test_endpoint_specific(mock_client): def factory(): return 1 def other_factory(): return 2 fuzz_lightyear.register_factory('string, integer')(factory) fuzz_lightyear.register_factory( 'string, integer', operation_ids='get_expect_other_primitives', )(other_factory) request = FuzzingRequest( operation_id='get_expect_primitives', tag='types', ) request.send() other_request = FuzzingRequest( operation_id='get_expect_other_primitives', tag='types', ) other_request.send() assert request.fuzzed_input['string'] == '1' assert request.fuzzed_input['integer'] == 1 assert other_request.fuzzed_input['string'] == '2' assert other_request.fuzzed_input['integer'] == 2
def test_str_encodes_array_path_parameters(mock_client): request = FuzzingRequest( operation_id='get_expect_path_array', tag='types', ids=[1, 2, 3], ) request.send() assert str(request) == (f'curl -X GET {URL}/types/path_array/1%2C2%2C3')
def test_success(self, mock_client): def factory(): return 1 fuzz_lightyear.register_factory('id')(factory) request = FuzzingRequest( operation_id='get_public_listing', tag='basic', ) request.send() assert request.fuzzed_input['id'] == 1
def test_send_body(mock_client): request = FuzzingRequest( operation_id='post_nested_model', tag='complex', ) # We need to trigger the parameters to be fuzzed. request.send() assert str(request) == ( f'curl -X POST {URL}/complex/nested ' f'--data \'{json.dumps(request.fuzzed_input["payload"])}\' ' '-H \'Content-Type: application/json\' ' '-H \'Cookie: session=victim_session\'')
def test_type_hinting(mock_client): def factory(): return 1 fuzz_lightyear.register_factory('string, integer')(factory) request = FuzzingRequest( operation_id='get_expect_primitives', tag='types', ) request.send() assert request.fuzzed_input['string'] == '1' assert request.fuzzed_input['integer'] == 1
def test_exclude_parameter(self, mock_client): def factory(): return None fuzz_lightyear.register_factory('id')(factory) request = FuzzingRequest( operation_id='get_public_listing', tag='basic', ) # id is a required parameter, so this will raise, if the id isn't # provided (as expected) with pytest.raises(SwaggerMappingError): request.send()
def test_nested(self, mock_client): def factory(): return 'test_value' fuzz_lightyear.register_factory('session')(factory) request = FuzzingRequest( operation_id='post_nested_model', tag='complex', ) request.send() assert request.fuzzed_input['payload']['info'][ 'session'] == 'test_value'
def test_send_basic_request(mock_client): request = FuzzingRequest( operation_id='get_no_inputs_required', tag='basic', ) assert request.send().session == 'victim_session'
def test_fuzz_enum(mock_client): request = FuzzingRequest( operation_id='get_will_throw_error', tag='constant', ) with pytest.raises(HTTPError): request.send() assert request.fuzzed_input['code'] in [ 400, 401, 403, 404, 500, ]
def test_send_specified_auth(mock_client): request = FuzzingRequest( operation_id='get_no_inputs_required', tag='basic', ) assert request.send(auth=get_abstraction().get_attacker_session(), ).session == 'attacker_session'
def test_fuzzed_request(tag, id, mock_client): request = FuzzingRequest( tag=tag, operation_id=id, ) response = request.send() assert response.value == 'ok'
def test_post_fuzz_hook( mock_client, decorator_args, fuzzing_request_args, expected_headers, ): def post_fuzz_hook(operation, fuzzed_input): if '_request_options' not in fuzzed_input: fuzzed_input['_request_options'] = {} if 'headers' not in fuzzed_input['_request_options']: fuzzed_input['_request_options']['headers'] = {} fuzzed_input['_request_options']['headers']['__test__'] = 'test' fuzz_lightyear.hooks.post_fuzz(**decorator_args)(post_fuzz_hook) request = FuzzingRequest(**fuzzing_request_args) request.send() request_headers = request.fuzzed_input.get('_request_options', {}).get('headers', {}) assert request_headers == expected_headers
def test_rerun_post_fuzz_hook(mock_client, decorator_args, fuzzing_request_args): def nonce_post_fuzz_hook(operation, fuzzed_input): if '_request_options' not in fuzzed_input: fuzzed_input['_request_options'] = {} if 'headers' not in fuzzed_input['_request_options']: fuzzed_input['_request_options']['headers'] = {} fuzzed_input['_request_options']['headers']['__nonce__'] = \ base64.b64encode(os.urandom(4)).decode() fuzz_lightyear.hooks.post_fuzz(**decorator_args)(nonce_post_fuzz_hook) request = FuzzingRequest(**fuzzing_request_args) request.send() original_nonce = request.fuzzed_input['_request_options']['headers'][ '__nonce__'] request.send() new_nonce = request.fuzzed_input['_request_options']['headers'][ '__nonce__'] assert new_nonce != original_nonce
def test_send_endpoint_auth(mock_client): request = FuzzingRequest( operation_id='get_no_inputs_required', tag='basic', ) fuzz_lightyear.attacker_account( lambda operation_id: { '_request_options': { 'headers': { 'Cookie': 'session=' + operation_id, }, }, }, ) assert request.send(auth=get_abstraction().get_attacker_session, ).session == 'get_no_inputs_required'