diff --git a/w3af/core/data/parsers/doc/open_api/specification.py b/w3af/core/data/parsers/doc/open_api/specification.py index 4aaa93344e..dc338fcf72 100644 --- a/w3af/core/data/parsers/doc/open_api/specification.py +++ b/w3af/core/data/parsers/doc/open_api/specification.py @@ -21,7 +21,6 @@ """ import json -import yaml import logging from yaml import load @@ -232,7 +231,8 @@ def _load_spec_dict(self): :return: The dict with the open api data """ try: - spec_dict = json.loads(self.http_response.body) + decoded_response = self.http_response.body.decode('ascii', 'ignore') + spec_dict = json.loads(decoded_response) except ValueError: # Seems like the OpenAPI was specified using Yaml instead of # JSON. Let's parse the Yaml data! diff --git a/w3af/core/data/parsers/doc/open_api/tests/data/swagger-special-chars.json b/w3af/core/data/parsers/doc/open_api/tests/data/swagger-special-chars.json new file mode 100644 index 0000000000..a3eeff15d9 --- /dev/null +++ b/w3af/core/data/parsers/doc/open_api/tests/data/swagger-special-chars.json @@ -0,0 +1,73 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore, special chars: ąęćźżó^żć√≤Ķńå", + "description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "Swagger API Team" + }, + "license": { + "name": "MIT" + } + }, + "host": "petstore.swagger.io", + "basePath": "/api", + "schemes": [ + "http" + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/pets": { + "get": { + "description": "Returns all pets from the system that the user has access to", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "A list of pets.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Pet" + } + } + } + } + } + }, + "/pets/{ąęćźżó^żć√≤Ķńå}": { + "get": { + "description": "Let's see if I'll return an error" + } + } + }, + "definitions": { + "Pet": { + "type": "object", + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + } + } +} diff --git a/w3af/core/data/parsers/doc/open_api/tests/test_specification.py b/w3af/core/data/parsers/doc/open_api/tests/test_specification.py index e6e96efb6a..3eb9636167 100644 --- a/w3af/core/data/parsers/doc/open_api/tests/test_specification.py +++ b/w3af/core/data/parsers/doc/open_api/tests/test_specification.py @@ -595,6 +595,18 @@ def test_parameter_handler_multiple_paths_and_headers(self): handler = SpecificationHandler(http_response) self.check_parameter_setting(handler) + def test_specification_handler_can_handle_spec_with_non_ascii_chars(self): + with open( + 'w3af/core/data/parsers/doc/open_api/tests/data/swagger-special-chars.json', + ) as file_: + spec_as_string = file_.read() + http_response = self.generate_response(spec_as_string) + spec_handler = SpecificationHandler(http_response) + result = spec_handler.get_api_information() + for _ in result: + pass + self.assertFalse(spec_handler._parsing_errors) + def check_parameter_setting(self, spec_handler): data = [d for d in spec_handler.get_api_information()] self.assertIsNotNone(data)