Ejemplo n.º 1
0
    def test_disabling_spec_validation(self):
        body = file(self.NOT_VALID_SPEC).read()
        headers = Headers({'Content-Type': 'application/json'}.items())
        response = HTTPResponse(200,
                                body,
                                headers,
                                URL('http://moth/swagger.json'),
                                URL('http://moth/swagger.json'),
                                _id=1)

        parser = OpenAPI(response)
        parser.parse()
        api_calls = parser.get_api_calls()
        self.assertEqual(len(api_calls), 0)

        parser = OpenAPI(response, no_validation=True)
        parser.parse()
        api_calls = parser.get_api_calls()
        self.assertEqual(len(api_calls), 1)

        api_call = api_calls[0]
        e_url = 'http://w3af.org/api/pets'
        e_force_fuzzing_headers = []
        e_headers = Headers([('Content-Type', 'application/json')])
        e_body = '{"pet": {"age": 42}}'

        self.assertEqual(api_call.get_method(), 'POST')
        self.assertEqual(api_call.get_uri().url_string, e_url)
        self.assertEquals(api_call.get_headers(), e_headers)
        self.assertEqual(api_call.get_force_fuzzing_headers(),
                         e_force_fuzzing_headers)
        self.assertEqual(api_call.get_data(), e_body)
Ejemplo n.º 2
0
    def test_custom_content_type(self):
        body = file(self.CUSTOM_CONTENT_TYPE).read()
        headers = Headers({'Content-Type': 'application/json'}.items())
        response = HTTPResponse(200, body, headers,
                                URL('http://moth/swagger.json'),
                                URL('http://moth/swagger.json'),
                                _id=1)

        parser = OpenAPI(response)
        parser.parse()
        api_calls = parser.get_api_calls()

        api_calls.sort(by_path)

        self.assertEqual(len(api_calls), 2)

        #
        # Assertions on call #1
        #
        api_call = api_calls[0]

        e_url = 'http://w3af.org/api/pets'
        e_force_fuzzing_headers = []
        e_headers = Headers([('Content-Type', 'application/vnd.w3af+json')])
        e_post_data_headers = Headers([('Content-Type', 'application/vnd.w3af+json')])
        e_all_headers = Headers([('Content-Type', 'application/vnd.w3af+json')])

        self.assertIsInstance(api_call.get_raw_data(), JSONContainer)
        self.assertEquals(api_call.get_method(), 'PUT')
        self.assertEquals(api_call.get_uri().url_string, e_url)
        self.assertEquals(api_call.get_headers(), e_headers)
        self.assertEquals(api_call.get_post_data_headers(), e_post_data_headers)
        self.assertEquals(api_call.get_all_headers(), e_all_headers)
        self.assertEquals(api_call.get_force_fuzzing_headers(), e_force_fuzzing_headers)
        self.assertEquals(str(api_call.get_raw_data()), '{"info": {"tag": "7", "name": "John", "id": 42}}')

        #
        # Assertions on call #2
        #
        api_call = api_calls[1]

        e_url = 'http://w3af.org/api/pets'
        e_force_fuzzing_headers = ['X-Foo-Header']
        e_headers = Headers([('Content-Type', 'application/vnd.w3af+json'), ('X-Foo-Header', '42')])
        e_post_data_headers = Headers([('Content-Type', 'application/vnd.w3af+json')])
        e_all_headers = Headers([('Content-Type', 'application/vnd.w3af+json'), ('X-Foo-Header', '42')])

        self.assertIsInstance(api_call.get_raw_data(), JSONContainer)
        self.assertEquals(api_call.get_method(), 'POST')
        self.assertEquals(api_call.get_uri().url_string, e_url)
        self.assertEquals(api_call.get_headers(), e_headers)
        self.assertEquals(api_call.get_post_data_headers(), e_post_data_headers)
        self.assertEquals(api_call.get_all_headers(), e_all_headers)
        self.assertEquals(api_call.get_force_fuzzing_headers(), e_force_fuzzing_headers)
        self.assertEquals(str(api_call.get_raw_data()), '{"info": {"tag": "7", "name": "John"}}')
Ejemplo n.º 3
0
    def test_custom_content_type(self):
        body = file(self.CUSTOM_CONTENT_TYPE).read()
        headers = Headers({'Content-Type': 'application/json'}.items())
        response = HTTPResponse(200, body, headers,
                                URL('http://moth/swagger.json'),
                                URL('http://moth/swagger.json'),
                                _id=1)

        parser = OpenAPI(response)
        parser.parse()
        api_calls = parser.get_api_calls()

        api_calls.sort(by_path)

        self.assertEqual(len(api_calls), 2)

        #
        # Assertions on call #1
        #
        api_call = api_calls[0]

        e_url = 'http://w3af.org/api/pets'
        e_force_fuzzing_headers = []
        e_headers = Headers([('Content-Type', 'application/vnd.w3af+json')])
        e_post_data_headers = Headers([('Content-Type', 'application/vnd.w3af+json')])
        e_all_headers = Headers([('Content-Type', 'application/vnd.w3af+json')])

        self.assertIsInstance(api_call.get_raw_data(), JSONContainer)
        self.assertEquals(api_call.get_method(), 'PUT')
        self.assertEquals(api_call.get_uri().url_string, e_url)
        self.assertEquals(api_call.get_headers(), e_headers)
        self.assertEquals(api_call.get_post_data_headers(), e_post_data_headers)
        self.assertEquals(api_call.get_all_headers(), e_all_headers)
        self.assertEquals(api_call.get_force_fuzzing_headers(), e_force_fuzzing_headers)
        self.assertEquals(str(api_call.get_raw_data()), '{"info": {"tag": "7", "name": "John", "id": 42}}')

        #
        # Assertions on call #2
        #
        api_call = api_calls[1]

        e_url = 'http://w3af.org/api/pets'
        e_force_fuzzing_headers = ['X-Foo-Header']
        e_headers = Headers([('Content-Type', 'application/vnd.w3af+json'), ('X-Foo-Header', '42')])
        e_post_data_headers = Headers([('Content-Type', 'application/vnd.w3af+json')])
        e_all_headers = Headers([('Content-Type', 'application/vnd.w3af+json'), ('X-Foo-Header', '42')])

        self.assertIsInstance(api_call.get_raw_data(), JSONContainer)
        self.assertEquals(api_call.get_method(), 'POST')
        self.assertEquals(api_call.get_uri().url_string, e_url)
        self.assertEquals(api_call.get_headers(), e_headers)
        self.assertEquals(api_call.get_post_data_headers(), e_post_data_headers)
        self.assertEquals(api_call.get_all_headers(), e_all_headers)
        self.assertEquals(api_call.get_force_fuzzing_headers(), e_force_fuzzing_headers)
        self.assertEquals(str(api_call.get_raw_data()), '{"info": {"tag": "7", "name": "John"}}')
Ejemplo n.º 4
0
    def test_unknown_content_type(self):
        body = file(self.UNKNOWN_CONTENT_TYPE).read()
        headers = Headers({'Content-Type': 'application/json'}.items())
        response = HTTPResponse(200, body, headers,
                                URL('http://moth/swagger.json'),
                                URL('http://moth/swagger.json'),
                                _id=1)

        parser = OpenAPI(response)
        parser.parse()
        api_calls = parser.get_api_calls()
        self.assertEquals(api_calls, [])
Ejemplo n.º 5
0
    def test_unknown_content_type(self):
        body = file(self.UNKNOWN_CONTENT_TYPE).read()
        headers = Headers({'Content-Type': 'application/json'}.items())
        response = HTTPResponse(200, body, headers,
                                URL('http://moth/swagger.json'),
                                URL('http://moth/swagger.json'),
                                _id=1)

        parser = OpenAPI(response)
        parser.parse()
        api_calls = parser.get_api_calls()
        self.assertEquals(api_calls, [])
Ejemplo n.º 6
0
    def test_disabling_spec_validation(self):
        body = file(self.NOT_VALID_SPEC).read()
        headers = Headers({'Content-Type': 'application/json'}.items())
        response = HTTPResponse(200, body, headers,
                                URL('http://moth/swagger.json'),
                                URL('http://moth/swagger.json'),
                                _id=1)

        parser = OpenAPI(response)
        parser.parse()
        api_calls = parser.get_api_calls()
        self.assertEqual(len(api_calls), 0)

        parser = OpenAPI(response, no_validation=True)
        parser.parse()
        api_calls = parser.get_api_calls()
        self.assertEqual(len(api_calls), 1)

        api_call = api_calls[0]
        e_url = 'http://w3af.org/api/pets'
        e_force_fuzzing_headers = []
        e_headers = Headers([('Content-Type', 'application/json')])
        e_body = '{"pet": {"age": 42}}'

        self.assertEqual(api_call.get_method(), 'POST')
        self.assertEqual(api_call.get_uri().url_string, e_url)
        self.assertEquals(api_call.get_headers(), e_headers)
        self.assertEqual(api_call.get_force_fuzzing_headers(), e_force_fuzzing_headers)
        self.assertEqual(api_call.get_data(), e_body)
Ejemplo n.º 7
0
    def _extract_api_calls_from_response(self, spec_url, http_response):
        """
        Try to parse an API specification from an HTTP response.
        Send all the newly found fuzzable requests to the core
        after adding any authentication data that might have been configured.

        :parm spec_url: A URL to API specification
        :param http_response: An HTTP response
        :return: None
        """
        if not OpenAPI.can_parse(http_response):
            return

        om.out.debug('OpenAPI parser is about to parse %s' % spec_url)

        parser = OpenAPI(http_response, self._no_spec_validation,
                         self._discover_fuzzable_headers,
                         self._discover_fuzzable_url_parts)
        parser.parse()

        self._report_to_kb_if_needed(http_response, parser)
        self._send_spec_to_core(spec_url)

        om.out.debug('OpenAPI parser identified %s API calls' %
                     len(parser.get_api_calls()))

        for api_call in parser.get_api_calls():
            if not self._is_target_domain(api_call):
                continue

            api_call = self._set_authentication_data(api_call)
            self.output_queue.put(api_call)
Ejemplo n.º 8
0
    def test_large_many_endpoints(self):
        body = file(self.LARGE_MANY_ENDPOINTS).read()
        headers = Headers({'Content-Type': 'application/json'}.items())
        response = HTTPResponse(200, body, headers,
                                URL('http://moth/swagger.json'),
                                URL('http://moth/swagger.json'),
                                _id=1)

        parser = OpenAPI(response)
        parser.parse()
        api_calls = parser.get_api_calls()

        expected_api_calls = 161
        self.assertEqual(expected_api_calls, len(api_calls))

        first_api_call = api_calls[0]
        uri = first_api_call.get_uri().url_string

        expected_uri = 'https://target.com/api/Partners/3419/Agreement?performedBy=56'

        self.assertEqual(expected_uri, uri)
Ejemplo n.º 9
0
    def test_issue_210(self):
        body = file(self.ISSUE_210_API_YAML).read()
        headers = Headers({'Content-Type': 'application/yaml'}.items())
        response = HTTPResponse(200,
                                body,
                                headers,
                                URL('http://moth/swagger.yaml'),
                                URL('http://moth/swagger.yaml'),
                                _id=1)

        self.assertTrue(OpenAPI.can_parse(response))

        parser = OpenAPI(response)
        parser.parse()
        api_calls = parser.get_api_calls()

        expected_api_calls = 19
        self.assertEqual(expected_api_calls, len(api_calls))

        first_api_call = api_calls[0]
        uri = first_api_call.get_uri().url_string

        expected_uri = 'https://api.domain.com/domain/tokens'

        self.assertEqual(expected_uri, uri)
Ejemplo n.º 10
0
    def test_missing_license_name(self):
        body = file(self.MISSING_LICENSE).read()
        headers = Headers({'Content-Type': 'application/json'}.items())
        response = HTTPResponse(200,
                                body,
                                headers,
                                URL('http://moth/swagger.json'),
                                URL('http://moth/swagger.json'),
                                _id=1)

        parser = OpenAPI(response)
        parser.parse()
        api_calls = parser.get_api_calls()

        expected_api_calls = 5
        self.assertEqual(expected_api_calls, len(api_calls))

        first_api_call = api_calls[0]
        uri = first_api_call.get_uri().url_string

        expected_uri = 'http://1.2.3.4/api/prod/2.0/employees/3419'

        self.assertEqual(expected_uri, uri)
Ejemplo n.º 11
0
    def test_fuzing_on_invalid_token_path(self):
        body = file(self.INVALID_TOKEN_PATH).read()
        headers = Headers({'Content-Type': 'application/json'}.items())
        response = HTTPResponse(200,
                                body,
                                headers,
                                URL('http://moth/swagger.json'),
                                URL('http://moth/swagger.json'),
                                _id=1)

        self.assertTrue(OpenAPI.can_parse(response))

        parser = OpenAPI(response)
        parser.parse()
        api_calls = parser.get_api_calls()

        for api_call in api_calls:

            fake_mutants = create_mutants(api_call, [''])

            for mutant in fake_mutants:
                create_mutants(mutant.get_fuzzable_request(), [''],
                               fuzzable_param_list=[mutant.get_token_name()])
Ejemplo n.º 12
0
    def test_json_pet_store(self):
        # http://petstore.swagger.io/v2/swagger.json
        body = file(self.SWAGGER_JSON).read()
        headers = Headers({'Content-Type': 'application/json'}.items())
        response = HTTPResponse(200,
                                body,
                                headers,
                                URL('http://moth/swagger.json'),
                                URL('http://moth/swagger.json'),
                                _id=1)

        self.assertTrue(OpenAPI.can_parse(response))

        parser = OpenAPI(response)
        parser.parse()
        api_calls = parser.get_api_calls()

        json_headers = Headers([('Content-Type', 'application/json')])
        multipart_headers = Headers([('Content-Type', 'multipart/form-data')])
        url_encoded_headers = Headers([('Content-Type',
                                        'application/x-www-form-urlencoded')])
        json_api_headers = Headers([('api_key', 'FrAmE30.'),
                                    ('Content-Type', 'application/json')])

        url_root = 'http://petstore.swagger.io/v2'

        expected_body_1 = ('{"body": {"category": {"id": 42, "name": "John"},'
                           ' "status": "available", "name": "doggie",'
                           ' "tags": [{"id": 42, "name": "John"}],'
                           ' "photoUrls": ["56"], "id": 42}}')

        expected_body_2 = (
            '{"body": {"username": "******", "firstName": "John",'
            ' "lastName": "Smith", "userStatus": 42,'
            ' "email": "*****@*****.**", "phone": "55550178",'
            ' "password": "******", "id": 42}}')

        expected_body_3 = (
            '{"body": [{"username": "******", "firstName": "John",'
            ' "lastName": "Smith", "userStatus": 42,'
            ' "email": "*****@*****.**", "phone": "55550178",'
            ' "password": "******", "id": 42}]}')

        expected_body_4 = (
            '{"body": {"status": "placed",'
            ' "shipDate": "2017-06-30T23:59:45",'
            ' "complete": false, "petId": 42, "id": 42, "quantity": 42}}')

        e_api_calls = [
            ('GET', '/pet/findByStatus?status=available', json_headers, ''),
            ('POST', '/pet/42/uploadImage', multipart_headers, ''),
            ('POST', '/pet/42', url_encoded_headers, ''),
            ('POST', '/pet', json_headers, expected_body_1),
            ('GET', '/pet/42', json_headers, ''),
            ('GET', '/pet/42', json_api_headers, ''),
            ('GET', '/pet/findByTags?tags=56', json_headers, ''),
            ('PUT', '/pet', json_headers, expected_body_1),
            ('PUT', '/user/John8212', json_headers, expected_body_2),
            ('POST', '/user/createWithList', json_headers, expected_body_3),
            ('POST', '/user', json_headers, expected_body_2),
            ('GET', '/user/John8212', json_headers, ''),
            ('GET', '/user/login?username=John8212&password=FrAmE30.',
             json_headers, ''),
            ('GET', '/user/logout', Headers(), ''),
            ('POST', '/user/createWithArray', json_headers, expected_body_3),
            ('GET', '/store/order/2', json_headers, ''),
            ('GET', '/store/inventory', json_headers, ''),
            ('GET', '/store/inventory', json_api_headers, ''),
            ('POST', '/store/order', json_headers, expected_body_4),
        ]

        self.assertEqual(21, len(api_calls))

        for api_call in api_calls:
            method = api_call.get_method()
            headers = api_call.get_headers()
            data = api_call.get_data()

            uri = api_call.get_uri().url_string
            uri = uri.replace(url_root, '')

            data = (method, uri, headers, data)

            self.assertIn(data, e_api_calls)
Ejemplo n.º 13
0
    def test_real_api_yaml(self):
        body = file(self.REAL_API_YAML).read()
        headers = Headers({'Content-Type': 'application/yaml'}.items())
        response = HTTPResponse(200,
                                body,
                                headers,
                                URL('http://moth/swagger.yaml'),
                                URL('http://moth/swagger.yaml'),
                                _id=1)

        self.assertTrue(OpenAPI.can_parse(response))

        parser = OpenAPI(response)
        parser.parse()
        api_calls = parser.get_api_calls()

        e_api_calls = [
            ('GET',
             u'https://w3af.org/bankid/tokens/4271a25e-7211-4306-b527-46196eb2af28',
             Headers([(u'Content-Type', u'application/json')]), ''),
            ('POST', u'https://w3af.org/bankid/tokens',
             Headers([(u'Content-Type', u'application/json')]),
             '{"body": null}'),
            ('POST', u'https://w3af.org/bankid/tokens',
             Headers([(u'Content-Type', u'application/json'),
                      (u'Authorization', u'FrAmE30.')]),
             '{"body": {"orderRef": "e475f288-4e9b-43ea-966c-d3912e7a25b2"}}'),
            ('POST', u'https://w3af.org/bankid/orders',
             Headers([(u'Content-Type', u'application/json')]),
             '{"body": null}'),
            ('POST', u'https://w3af.org/bankid/orders',
             Headers([(u'Content-Type', u'application/json')]),
             '{"body": {"pid": "191212121212"}}'),
            ('GET', u'https://w3af.org/persons/3419/partners',
             Headers([(u'Content-Type', u'application/json')]), ''),
            ('GET', u'https://w3af.org/persons/3419/partners',
             Headers([(u'Authorization', u'FrAmE30.'),
                      (u'Content-Type', u'application/json')]), ''),
            ('GET', u'https://w3af.org/persons/3419/partners/3419',
             Headers([(u'Content-Type', u'application/json')]), ''),
            ('GET', u'https://w3af.org/persons/3419/partners/3419',
             Headers([(u'Authorization', u'FrAmE30.'),
                      (u'Content-Type', u'application/json')]), ''),
            ('GET', u'https://w3af.org/persons/3419',
             Headers([(u'Content-Type', u'application/json')]), ''),
            ('GET', u'https://w3af.org/persons/3419',
             Headers([(u'Authorization', u'FrAmE30.'),
                      (u'Content-Type', u'application/json')]), ''),
            ('POST', u'https://w3af.org/persons/3419/partners',
             Headers([(u'Content-Type', u'application/json')]),
             '{"body": null}'),
            ('POST', u'https://w3af.org/persons/3419/partners',
             Headers([(u'Content-Type', u'application/json'),
                      (u'Authorization', u'FrAmE30.')]),
             '{"body": {"partner": "19101010****", "termsAccepted": false}}'),
            ('PATCH', u'https://w3af.org/persons/3419',
             Headers([(u'Content-Type', u'application/json')]),
             '{"body": null}'),
            ('PATCH', u'https://w3af.org/persons/3419',
             Headers([(u'Content-Type', u'application/json'),
                      (u'Authorization', u'FrAmE30.')]),
             '{"body": {"termsAccepted": false}}'),
            ('PUT', u'https://w3af.org/persons/3419/partners/3419',
             Headers([(u'Content-Type', u'application/json')]),
             '{"body": null}'),
            ('PUT', u'https://w3af.org/persons/3419/partners/3419',
             Headers([(u'Content-Type', u'application/json'),
                      (u'Authorization', u'FrAmE30.')]),
             '{"body": {"partner": "19101010****", "termsAccepted": false}}'),
            ('POST', u'https://w3af.org/events',
             Headers([(u'Content-Type', u'application/json')]),
             '{"body": null}'),
            ('POST', u'https://w3af.org/events',
             Headers([(u'Content-Type', u'application/json'),
                      (u'Authorization', u'FrAmE30.')]),
             '{"body": {"event": "start doktor24"}}')
        ]

        self.assertEqual(19, len(api_calls))

        for api_call in api_calls:
            method = api_call.get_method()
            headers = api_call.get_headers()
            data = api_call.get_data()

            uri = api_call.get_uri().url_string

            _tuple = (method, uri, headers, data)
            self.assertIn(_tuple, e_api_calls)
Ejemplo n.º 14
0
 def test_can_parse_content_type_with_keywords(self):
     # JSON content type
     # Contains keywords
     # Invalid JSON format
     http_resp = self.generate_response('"')
     self.assertFalse(OpenAPI.can_parse(http_resp))
Ejemplo n.º 15
0
 def test_is_valid_json_or_yaml_false(self):
     http_resp = self.generate_response('"', 'image/jpeg')
     self.assertFalse(OpenAPI.is_valid_json_or_yaml(http_resp))
Ejemplo n.º 16
0
 def test_matches_any_keyword_false(self):
     http_resp = self.generate_response('{"none": "fail"}')
     self.assertFalse(OpenAPI.matches_any_keyword(http_resp))
Ejemplo n.º 17
0
 def test_content_type_match_false(self):
     http_resp = self.generate_response('', 'image/jpeg')
     self.assertFalse(OpenAPI.content_type_match(http_resp))
Ejemplo n.º 18
0
 def test_can_parse_invalid_yaml_with_keywords(self):
     # Yaml content type
     # Contains keywords
     # Invalid yaml format
     http_resp = self.generate_response('{}', 'application/yaml')
     self.assertFalse(OpenAPI.can_parse(http_resp))
Ejemplo n.º 19
0
    def test_is_valid_json_or_yaml_true(self):
        http_resp = self.generate_response('{}')
        self.assertTrue(OpenAPI.is_valid_json_or_yaml(http_resp))

        http_resp = self.generate_response('', 'application/yaml')
        self.assertTrue(OpenAPI.is_valid_json_or_yaml(http_resp))
Ejemplo n.º 20
0
 def test_matches_any_keyword_false(self):
     http_resp = self.generate_response('{"none": "fail"}')
     self.assertFalse(OpenAPI.matches_any_keyword(http_resp))
Ejemplo n.º 21
0
 def test_matches_any_keyword_true(self):
     http_resp = self.generate_response('{"consumes": "application/json"}')
     self.assertTrue(OpenAPI.matches_any_keyword(http_resp))
Ejemplo n.º 22
0
 def test_content_type_match_false(self):
     http_resp = self.generate_response('', 'image/jpeg')
     self.assertFalse(OpenAPI.content_type_match(http_resp))
Ejemplo n.º 23
0
 def test_content_type_match_true(self):
     http_resp = self.generate_response('{}')
     self.assertTrue(OpenAPI.content_type_match(http_resp))
Ejemplo n.º 24
0
 def test_can_parse_invalid_yaml_with_keywords(self):
     # Yaml content type
     # Contains keywords
     # Invalid yaml format
     http_resp = self.generate_response('{}', 'application/yaml')
     self.assertFalse(OpenAPI.can_parse(http_resp))
Ejemplo n.º 25
0
 def test_can_parse_content_type_no_keywords(self):
     # JSON content type
     # Does NOT contain keywords
     http_resp = self.generate_response('{}')
     self.assertFalse(OpenAPI.can_parse(http_resp))
Ejemplo n.º 26
0
 def test_can_parse_content_type_with_keywords(self):
     # JSON content type
     # Contains keywords
     # Invalid JSON format
     http_resp = self.generate_response('"')
     self.assertFalse(OpenAPI.can_parse(http_resp))
Ejemplo n.º 27
0
    def test_disabling_headers_discovery(self):
        body = file(self.MULTIPLE_PATHS_AND_HEADERS).read()
        headers = Headers({'Content-Type': 'application/json'}.items())
        response = HTTPResponse(200, body, headers,
                                URL('http://moth/swagger.json'),
                                URL('http://moth/swagger.json'),
                                _id=1)

        parser = OpenAPI(response, discover_fuzzable_headers=False)
        parser.parse()
        api_calls = parser.get_api_calls()

        api_calls.sort(by_path)

        self.assertEqual(len(api_calls), 4)

        e_force_fuzzing_headers = []

        #
        # Assertions on call #1
        #
        api_call = api_calls[0]

        e_url = 'http://w3af.org/api/cats'
        e_headers = Headers([
            ('X-Awesome-Header', '2018'),
            ('X-Foo-Header', 'foo'),
            ('Content-Type', 'application/json')])

        self.assertEqual(api_call.get_method(), 'GET')
        self.assertEqual(api_call.get_uri().url_string, e_url)
        self.assertEquals(api_call.get_headers(), e_headers)
        self.assertEqual(api_call.get_force_fuzzing_headers(), e_force_fuzzing_headers)

        #
        # Assertions on call #2
        #
        api_call = api_calls[1]

        e_url = 'http://w3af.org/api/cats?limit=42'
        e_headers = Headers([
            ('X-Awesome-Header', '2018'),
            ('X-Foo-Header', 'foo'),
            ('Content-Type', 'application/json')])

        self.assertEqual(api_call.get_method(), 'GET')
        self.assertEqual(api_call.get_uri().url_string, e_url)
        self.assertEquals(api_call.get_headers(), e_headers)
        self.assertEqual(api_call.get_force_fuzzing_headers(), e_force_fuzzing_headers)

        #
        # Assertions on call #3
        #
        api_call = api_calls[2]

        e_url = 'http://w3af.org/api/pets'
        e_headers = Headers([
            ('X-Foo-Header', '42'),
            ('Content-Type', 'application/json')])

        self.assertEqual(api_call.get_method(), 'GET')
        self.assertEqual(api_call.get_uri().url_string, e_url)
        self.assertEquals(api_call.get_headers(), e_headers)
        self.assertEqual(api_call.get_force_fuzzing_headers(), e_force_fuzzing_headers)

        #
        # Assertions on call #4
        #
        api_call = api_calls[3]

        e_url = 'http://w3af.org/api/pets'
        e_headers = Headers([
            ('X-Bar-Header', '56'),
            ('X-Foo-Header', '42'),
            ('Content-Type', 'application/json')])

        self.assertEqual(api_call.get_method(), 'GET')
        self.assertEqual(api_call.get_uri().url_string, e_url)
        self.assertEquals(api_call.get_headers(), e_headers)
        self.assertEqual(api_call.get_force_fuzzing_headers(), e_force_fuzzing_headers)
Ejemplo n.º 28
0
 def test_content_type_match_true(self):
     http_resp = self.generate_response('{}')
     self.assertTrue(OpenAPI.content_type_match(http_resp))
Ejemplo n.º 29
0
    def test_json_pet_store(self):
        # http://petstore.swagger.io/v2/swagger.json
        body = file(self.SWAGGER_JSON).read()
        headers = Headers({'Content-Type': 'application/json'}.items())
        response = HTTPResponse(200, body, headers,
                                URL('http://moth/swagger.json'),
                                URL('http://moth/swagger.json'),
                                _id=1)

        parser = OpenAPI(response)
        parser.parse()
        api_calls = parser.get_api_calls()

        json_headers = Headers([('Content-Type', 'application/json')])
        multipart_headers = Headers([('Content-Type', 'multipart/form-data')])
        url_encoded_headers = Headers([('Content-Type', 'application/x-www-form-urlencoded')])
        json_api_headers = Headers([('api_key', 'FrAmE30.'),
                                    ('Content-Type', 'application/json')])

        url_root = 'http://petstore.swagger.io/v2'

        expected_body_1 = ('{"body": {"category": {"id": 42, "name": "John"},'
                           ' "status": "available", "name": "John",'
                           ' "tags": [{"id": 42, "name": "John"}],'
                           ' "photoUrls": ["56"], "id": 42}}')

        expected_body_2 = ('{"body": {"username": "******", "firstName": "John",'
                           ' "lastName": "Smith", "userStatus": 42,'
                           ' "email": "*****@*****.**", "phone": "55550178",'
                           ' "password": "******", "id": 42}}')

        expected_body_3 = ('{"body": [{"username": "******", "firstName": "John",'
                           ' "lastName": "Smith", "userStatus": 42,'
                           ' "email": "*****@*****.**", "phone": "55550178",'
                           ' "password": "******", "id": 42}]}')

        expected_body_4 = ('{"body": {"status": "placed",'
                           ' "shipDate": "2017-06-30T23:59:45",'
                           ' "complete": true, "petId": 42, "id": 42, "quantity": 42}}')

        e_api_calls = [
            ('GET',  '/pet/findByStatus?status=available', json_headers, ''),
            ('POST', '/pet/42/uploadImage', multipart_headers, ''),
            ('POST', '/pet/42', url_encoded_headers, ''),
            ('POST', '/pet', json_headers, expected_body_1),
            ('GET',  '/pet/42', json_headers, ''),
            ('GET',  '/pet/42', json_api_headers, ''),
            ('GET',  '/pet/findByTags?tags=56', json_headers, ''),
            ('PUT',  '/pet', json_headers, expected_body_1),
            ('PUT',  '/user/John8212', json_headers, expected_body_2),
            ('POST', '/user/createWithList', json_headers, expected_body_3),
            ('POST', '/user', json_headers, expected_body_2),
            ('GET',  '/user/John8212', json_headers, ''),
            ('GET',  '/user/login?username=John8212&password=FrAmE30.', json_headers, ''),
            ('GET',  '/user/logout', Headers(), ''),
            ('POST', '/user/createWithArray', json_headers, expected_body_3),
            ('GET',  '/store/order/2', json_headers, ''),
            ('GET',  '/store/inventory', json_headers, ''),
            ('GET',  '/store/inventory', json_api_headers, ''),
            ('POST', '/store/order', json_headers, expected_body_4),
        ]

        for api_call in api_calls:
            method = api_call.get_method()
            headers = api_call.get_headers()
            data = api_call.get_data()

            uri = api_call.get_uri().url_string
            uri = uri.replace(url_root, '')

            data = (method, uri, headers, data)

            self.assertIn(data, e_api_calls)
Ejemplo n.º 30
0
 def test_matches_any_keyword_true(self):
     http_resp = self.generate_response('{"consumes": "application/json"}')
     self.assertTrue(OpenAPI.matches_any_keyword(http_resp))
Ejemplo n.º 31
0
    def test_large_many_endpoints(self):
        body = file(self.LARGE_MANY_ENDPOINTS).read()
        headers = Headers({'Content-Type': 'application/json'}.items())
        response = HTTPResponse(200,
                                body,
                                headers,
                                URL('http://moth/swagger.json'),
                                URL('http://moth/swagger.json'),
                                _id=1)

        self.assertTrue(OpenAPI.can_parse(response))

        #
        # In some cases with validation enabled (not the default) we find a set
        # of endpoints:
        #
        parser = OpenAPI(response, validate_swagger_spec=True)
        parser.parse()
        api_calls = parser.get_api_calls()

        expected_api_calls = 161
        self.assertEqual(expected_api_calls, len(api_calls))

        #
        # And without spec validation there is a different set of endpoints:
        #
        parser = OpenAPI(response)
        parser.parse()
        api_calls = parser.get_api_calls()

        expected_api_calls = 165
        self.assertEqual(expected_api_calls, len(api_calls))

        first_api_call = api_calls[0]
        uri = first_api_call.get_uri().url_string

        expected_uri = 'https://target.com/api/Partners/3419/Agreement?performedBy=56'

        self.assertEqual(expected_uri, uri)
Ejemplo n.º 32
0
    def test_is_valid_json_or_yaml_true(self):
        http_resp = self.generate_response('{}')
        self.assertTrue(OpenAPI.is_valid_json_or_yaml(http_resp))

        http_resp = self.generate_response('', 'application/yaml')
        self.assertFalse(OpenAPI.is_valid_json_or_yaml(http_resp))
Ejemplo n.º 33
0
from w3af.core.data.parsers.doc.open_api import OpenAPI
from w3af.core.data.url.HTTPResponse import HTTPResponse

spec_filename = sys.argv[1]

_, extension = os.path.splitext(spec_filename)

body = file(spec_filename).read()
headers = Headers({'Content-Type': 'application/%s' % extension}.items())
response = HTTPResponse(200,
                        body,
                        headers,
                        URL('http://moth/swagger.%s' % extension),
                        URL('http://moth/swagger.%s' % extension),
                        _id=1)

parser = OpenAPI(response)
parser.parse()
api_calls = parser.get_api_calls()

for api_call in api_calls:
    method = api_call.get_method()
    headers = api_call.get_headers()
    data = api_call.get_data()

    uri = api_call.get_uri().url_string

    data = (method, uri, headers, data)

    pprint.pprint(data)
Ejemplo n.º 34
0
    def test_disabling_headers_discovery(self):
        body = file(self.MULTIPLE_PATHS_AND_HEADERS).read()
        headers = Headers({'Content-Type': 'application/json'}.items())
        response = HTTPResponse(200,
                                body,
                                headers,
                                URL('http://moth/swagger.json'),
                                URL('http://moth/swagger.json'),
                                _id=1)

        self.assertTrue(OpenAPI.can_parse(response))

        parser = OpenAPI(response, discover_fuzzable_headers=False)
        parser.parse()
        api_calls = parser.get_api_calls()

        api_calls.sort(by_path)

        self.assertEqual(len(api_calls), 4)

        e_force_fuzzing_headers = []

        #
        # Assertions on call #1
        #
        api_call = api_calls[0]

        e_url = 'http://w3af.org/api/cats'
        e_headers = Headers([('X-Awesome-Header', '2018'),
                             ('X-Foo-Header', 'foo'),
                             ('Content-Type', 'application/json')])

        self.assertEqual(api_call.get_method(), 'GET')
        self.assertEqual(api_call.get_uri().url_string, e_url)
        self.assertEquals(api_call.get_headers(), e_headers)
        self.assertEqual(api_call.get_force_fuzzing_headers(),
                         e_force_fuzzing_headers)

        #
        # Assertions on call #2
        #
        api_call = api_calls[1]

        e_url = 'http://w3af.org/api/cats?limit=42'
        e_headers = Headers([('X-Awesome-Header', '2018'),
                             ('X-Foo-Header', 'foo'),
                             ('Content-Type', 'application/json')])

        self.assertEqual(api_call.get_method(), 'GET')
        self.assertEqual(api_call.get_uri().url_string, e_url)
        self.assertEquals(api_call.get_headers(), e_headers)
        self.assertEqual(api_call.get_force_fuzzing_headers(),
                         e_force_fuzzing_headers)

        #
        # Assertions on call #3
        #
        api_call = api_calls[2]

        e_url = 'http://w3af.org/api/pets'
        e_headers = Headers([('X-Foo-Header', '42'),
                             ('Content-Type', 'application/json')])

        self.assertEqual(api_call.get_method(), 'GET')
        self.assertEqual(api_call.get_uri().url_string, e_url)
        self.assertEquals(api_call.get_headers(), e_headers)
        self.assertEqual(api_call.get_force_fuzzing_headers(),
                         e_force_fuzzing_headers)

        #
        # Assertions on call #4
        #
        api_call = api_calls[3]

        e_url = 'http://w3af.org/api/pets'
        e_headers = Headers([('X-Bar-Header', '56'), ('X-Foo-Header', '42'),
                             ('Content-Type', 'application/json')])

        self.assertEqual(api_call.get_method(), 'GET')
        self.assertEqual(api_call.get_uri().url_string, e_url)
        self.assertEquals(api_call.get_headers(), e_headers)
        self.assertEqual(api_call.get_force_fuzzing_headers(),
                         e_force_fuzzing_headers)
Ejemplo n.º 35
0
 def test_can_parse_content_type_no_keywords(self):
     # JSON content type
     # Does NOT contain keywords
     http_resp = self.generate_response('{}')
     self.assertFalse(OpenAPI.can_parse(http_resp))
Ejemplo n.º 36
0
 def test_is_valid_json_or_yaml_false(self):
     http_resp = self.generate_response('"', 'image/jpeg')
     self.assertFalse(OpenAPI.is_valid_json_or_yaml(http_resp))
Ejemplo n.º 37
0
    def test_disabling_spec_validation(self):
        body = file(self.NOT_VALID_SPEC).read()
        headers = Headers({'Content-Type': 'application/json'}.items())
        response = HTTPResponse(200,
                                body,
                                headers,
                                URL('http://moth/swagger.json'),
                                URL('http://moth/swagger.json'),
                                _id=1)

        self.assertTrue(OpenAPI.can_parse(response))

        #
        # By default we don't validate the swagger spec, which allows us to
        # parse some invalid specs and extract information
        #
        parser = OpenAPI(response)
        parser.parse()
        api_calls = parser.get_api_calls()
        self.assertEqual(len(api_calls), 1)

        api_call = api_calls[0]
        e_url = 'http://w3af.org/api/pets'
        e_force_fuzzing_headers = []
        e_headers = Headers([('Content-Type', 'application/json')])
        e_body = '{"pet": {"age": 42}}'

        self.assertEqual(api_call.get_method(), 'POST')
        self.assertEqual(api_call.get_uri().url_string, e_url)
        self.assertEquals(api_call.get_headers(), e_headers)
        self.assertEqual(api_call.get_force_fuzzing_headers(),
                         e_force_fuzzing_headers)
        self.assertEqual(api_call.get_data(), e_body)

        #
        # With validation enabled the parsing fails because there is a mising
        # required attribute
        #
        parser = OpenAPI(response, validate_swagger_spec=True)
        parser.parse()
        api_calls = parser.get_api_calls()
        self.assertEqual(len(api_calls), 0)