Ejemplo n.º 1
0
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)'
Ejemplo n.º 2
0
    def test_single_factory_usage(self, mock_client):
        current_id = 1234

        def create_resource():
            nonlocal current_id
            output = current_id
            current_id += 1

            return output
        fuzz_lightyear.register_factory('id')(create_resource)
        responses = validate_sequence(
            [
                FuzzingRequest(
                    tag='sequence',
                    operation_id='post_bravo_one',
                ),
                FuzzingRequest(
                    tag='sequence',
                    operation_id='get_bravo_two',
                ),
            ],
            ResponseSequence(),
        )

        assert responses.responses[-1] == 1234
        assert current_id != 1234
Ejemplo n.º 3
0
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'
Ejemplo n.º 4
0
def test_send_basic_request(mock_client):
    request = FuzzingRequest(
        operation_id='get_no_inputs_required',
        tag='basic',
    )

    assert request.send().session == 'victim_session'
Ejemplo n.º 5
0
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()
Ejemplo n.º 6
0
def test_fuzzed_request(tag, id, mock_client):
    request = FuzzingRequest(
        tag=tag,
        operation_id=id,
    )
    response = request.send()

    assert response.value == 'ok'
Ejemplo n.º 7
0
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'
Ejemplo n.º 8
0
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')
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
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\'')
Ejemplo n.º 12
0
    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()
Ejemplo n.º 13
0
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
Ejemplo n.º 14
0
    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'
Ejemplo n.º 15
0
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,
    ]
Ejemplo n.º 16
0
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'
Ejemplo n.º 17
0
    def test_basic(self, mock_client):
        responses = validate_sequence(
            [
                FuzzingRequest(
                    tag='sequence',
                    operation_id='post_alpha_one',
                ),
                FuzzingRequest(
                    tag='sequence',
                    operation_id='get_alpha_two',
                ),
            ],
            ResponseSequence(),
        )

        # This value is returned from `post_alpha_one`. If they were
        # independently fuzzed, it would not be this value.
        assert responses.responses[-1] == 'ok'
Ejemplo n.º 18
0
def test_str_encodes_array_query_parameters(mock_client):
    request = FuzzingRequest(
        operation_id='get_expect_array',
        tag='types',
        array=[
            True,
            False,
        ],
    )
    assert str(
        request) == f'curl -X GET {URL}/types/array?array=True&array=False'
Ejemplo n.º 19
0
def test_failed_sequence_should_not_be_successful(mock_client):
    result = FuzzingResult([
        FuzzingRequest(
            tag='sequence',
            operation_id='post_alpha_one',
        ),
        FuzzingRequest(
            tag='constant',
            operation_id='get_will_throw_error',
        ),
        FuzzingRequest(
            tag='sequence',
            operation_id='get_alpha_two',
        ),
    ])

    with pytest.raises(HTTPError):
        validate_sequence(result.requests, result.responses)

    assert not result.is_successful()
Ejemplo n.º 20
0
def test_invalid_request(mock_client):
    with pytest.raises(HTTPError):
        validate_sequence(
            [
                FuzzingRequest(
                    tag='constant',
                    operation_id='get_will_throw_error',
                    code=400,
                ),
            ],
            ResponseSequence(),
        )
Ejemplo n.º 21
0
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
Ejemplo n.º 22
0
def test_skipped_due_to_no_inputs(mock_client):
    responses = validate_sequence(
        [
            FuzzingRequest(
                tag='basic',
                operation_id='get_no_inputs_required',
            ),
        ],
        ResponseSequence(),
    )

    assert responses.data['session'] == 'victim_session'
    assert responses.test_results == {}
Ejemplo n.º 23
0
def test_side_effect_safe(mock_api_client):
    responses = validate_sequence(
        [
            FuzzingRequest(
                tag='sequence',
                operation_id='post_create_with_side_effect',
            ),
            FuzzingRequest(
                tag='user',
                operation_id='get_get_user',
            ),

            # This goes last, to test for IDOR.
            FuzzingRequest(
                tag='sequence',
                operation_id='get_get_with_side_effect_safe',
            ),
        ],
        ResponseSequence(),
    )

    assert responses.responses[1].created_resource
    assert not responses.test_results['IDORPlugin']
Ejemplo n.º 24
0
def test_basic(mock_client):
    responses = validate_sequence(
        [
            FuzzingRequest(
                tag='basic',
                operation_id='get_private_listing',
                id=1,
            ),
        ],
        ResponseSequence(),
    )

    assert responses.data['session'] == 'victim_session'
    assert responses.test_results['IDORPlugin']
Ejemplo n.º 25
0
def test_valid_request_skip_idor_manually_excluded(
    mock_client,
    non_vulnerable_operations,
):
    responses = validate_sequence(
        [
            FuzzingRequest(
                tag='basic',
                operation_id='get_public_listing',
            ),
        ],
        ResponseSequence(),
    )

    assert isinstance(responses.data['value'], str)
    assert responses.test_results == {}
Ejemplo n.º 26
0
    def mock_result(self, *cases, test_results=None, client=None):
        request_sequence = []
        for case in cases:
            request_sequence.append(FuzzingRequest(
                tag='test',
                **case,
            ), )

            if client:
                setattr(
                    client.test,
                    case['operation_id'],
                    self.mock_client_properties(**case),
                )

        result = FuzzingResult(request_sequence)
        result.responses = ResponseSequence()
        if test_results:
            result.responses.test_results = test_results

        return result
Ejemplo n.º 27
0
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
Ejemplo n.º 28
0
import pytest
from bravado.exception import HTTPError

from fuzz_lightyear.request import FuzzingRequest
from fuzz_lightyear.result import FuzzingResult
from fuzz_lightyear.runner import validate_sequence


@pytest.mark.parametrize(
    'sequence',
    (
        [
            FuzzingRequest(
                tag='sequence',
                operation_id='post_alpha_one',
            ),
        ],
        [
            FuzzingRequest(
                tag='sequence',
                operation_id='get_alpha_two',
            ),
        ],
    ),
)
def test_successful_sequence(mock_client, sequence):
    result = FuzzingResult(sequence)
    validate_sequence(result.requests, result.responses)

    assert result.is_successful()