From f8284cbb4b5ecca4d9721608621bdec1a198bb80 Mon Sep 17 00:00:00 2001 From: Darkiros Date: Mon, 24 Jun 2024 14:14:05 +0200 Subject: [PATCH] Improve Swagger base URL parsing and support openAPI 3.0 --- tests/data/openapi3.yaml | 119 +++++++++++++++++++++++++++ tests/parsers/test_swagger_parser.py | 10 +++ wapitiCore/parsers/swagger.py | 14 ++++ 3 files changed, 143 insertions(+) create mode 100644 tests/data/openapi3.yaml diff --git a/tests/data/openapi3.yaml b/tests/data/openapi3.yaml new file mode 100644 index 000000000..7db0da762 --- /dev/null +++ b/tests/data/openapi3.yaml @@ -0,0 +1,119 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Fake Swagger + license: + name: MIT +servers: + - url: https://{customerId}.openapi.fr:{port}/v1 + variables: + customerId: + default: fake + description: Customer ID assigned by the service provider + port: + enum: + - '443' + - '8443' + - '8080' + default: '8080' +paths: + /pets: + get: + summary: List all pets + operationId: listPets + tags: + - pets + parameters: + - name: limit + in: query + description: How many items to return at one time (max 100) + required: false + schema: + type: integer + format: int32 + responses: + 200: + description: An paged array of pets + headers: + x-next: + description: A link to the next page of responses + schema: + type: string + content: + application/json: + schema: + $ref: "#/components/schemas/Pets" + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + post: + summary: Create a pet + operationId: createPets + tags: + - pets + responses: + 201: + description: Null response + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + /pets/{petId}: + get: + summary: Info for a specific pet + operationId: showPetById + tags: + - pets + parameters: + - name: petId + in: path + required: true + description: The id of the pet to retrieve + schema: + type: string + responses: + 200: + description: Expected response to a valid request + content: + application/json: + schema: + $ref: "#/components/schemas/Pets" + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" +components: + schemas: + Pet: + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + Pets: + type: array + items: + $ref: "#/components/schemas/Pet" + Error: + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string diff --git a/tests/parsers/test_swagger_parser.py b/tests/parsers/test_swagger_parser.py index 91f180cfa..9eab53039 100644 --- a/tests/parsers/test_swagger_parser.py +++ b/tests/parsers/test_swagger_parser.py @@ -151,3 +151,13 @@ def test_openapi_yaml_file(): "https://fake.openapi.fr/eval?s=default", "https://fake.openapi.fr/help" } == {x.url for x in page.get_requests()} + +def test_openapi3(): + url = "tests/data/openapi3.yaml" + page = Swagger(base_url="https://fake.openapi.fr", swagger_url=url) + + assert{ + "https://fake.openapi.fr:8080/v1/pets?limit=1337", + "https://fake.openapi.fr:8080/v1/pets", + "https://fake.openapi.fr:8080/v1/pets/default" + } == {x.url for x in page.get_requests()} diff --git a/wapitiCore/parsers/swagger.py b/wapitiCore/parsers/swagger.py index 548b570e0..89199b09e 100644 --- a/wapitiCore/parsers/swagger.py +++ b/wapitiCore/parsers/swagger.py @@ -67,6 +67,20 @@ def __init__(self, swagger_url: str = None, base_url: str = None) -> None: def _get_base_url(swagger_dict: dict, url: str) -> str: try: parsed_host = urllib.parse.urlparse(url) + if 'servers' in swagger_dict: + for server in swagger_dict['servers']: + if 'url' in server and server['url'] != "": + if server['url'].endswith("/"): + server['url'] = server['url'][:-1] + swagger_url = server['url'] + if 'variables' in server: + for variable in server['variables']: + swagger_url = swagger_url.replace( + "{" + variable + "}", server['variables'][variable]['default'] + ) + swagger_dict['basePath'] = "" + swagger_dict['host'] = swagger_url + return swagger_url if 'schemes' not in swagger_dict: # get http or https from url swagger_dict['schemes'] = parsed_host.scheme