rest-api-fuzz-testing icon indicating copy to clipboard operation
rest-api-fuzz-testing copied to clipboard

ZAP wrong endpoint URL

Open Sticcia opened this issue 3 years ago • 5 comments

Running ZAP in a local deployment with the following configuration:

{
  "readOnlyFileShareMounts": [
    {
      "fileShareName": "specifications",
      "mountPath": "/specifications"
    }
  ],
  "testTasks": {
    "targetConfiguration": {
      "apiSpecifications": [
        "/specifications/openapi.json"
      ],
      "endpoint": "https://<endpoint-url>/managementserver/rest"
    },
    "tasks": [
      {
        "toolName": "ZAP",
        "outputFolder": "zap",
        "keyVaultSecrets": [
          "TOKEN"
        ],
        "authenticationMethod": {
          "Token": "Token"
        }
      }
    ]
  }
}

The openapi.json specification contains the following:

"servers": [
  {
    "url": "https://localhost/ManagementServer/rest",
    "description": "Management Server entry point"
  }
]

Execution runs tests against URL from specification instead of endpoint in configuration, causing many errors like:

14529 [ZAP-Import-OpenAPI-1] WARN  org.zaproxy.zap.extension.openapi.ExtensionOpenApi - Failed to access URL: https://localhost/ManagementServer/rest/cameras : java.net.ConnectException : Connection refused (Connection refused)
14529 [ZAP-Import-OpenAPI-1] WARN  org.zaproxy.zap.extension.openapi.ExtensionOpenApi - Failed to access URL: https://localhost/ManagementServer/rest/cameras/id?tasks=tasks : java.net.ConnectException : Connection refused (Connection refused)
14529 [ZAP-Import-OpenAPI-1] WARN  org.zaproxy.zap.extension.openapi.ExtensionOpenApi - Failed to access URL: https://localhost/ManagementServer/rest/cameras/id?task=task : java.net.ConnectException : Connection refused (Connection refused)

This happens only when using a mounted file path for the specification. Running a local python http.server on the host and changing the URL in the configuration to:

"apiSpecifications": [ "http://host.docker.internal:8000/openapi.json" ]

returns expected result. Lastly, all other tools work with:

"apiSpecifications": [ "/specifications/openapi.json" ]

Sticcia avatar Jul 02 '21 08:07 Sticcia

@Sticcia

Hi I cannot seem to be able to repro the issue

I am using petstore swagger specification https://petstore.swagger.io/v2/swagger.json and I added the following modification

image

I'm using the following RAFT job configuration file:

{
  "readonlyFileShareMounts": [
    {
      "FileShareName": "Zap-repro",
      "MountPath": "/specs"
    }
  ],
  "testTasks" : {
    "tasks": [
      {
        "toolName": "ZAP",
        "outputFolder": "zap-out",
        "targetConfiguration" : {
          "apiSpecifications": [
            "/specs/spec.json"
          ],
          "endpoint": "https://petstore.swagger.io"
        }
      }
    ]
  }
}

stishkin avatar Jul 02 '21 17:07 stishkin

Hi @stishkin ,

The modification should replace your "host" and "basePath" as seen here: https://swagger.io/docs/specification/api-host-and-base-path/ Or, my guess is, you could try changing from "host": "petstore.swagger.io" to "host": "localhost".

From what I understand, ZAP is grabbing the endpoint url from the specification (either "host" or "servers") instead of the configuration. So, having the spec differ from the config should suffice to reproduce this. (this happens only when using local mounted file, works fine if hosting i.e. Python server)

Also, I tried removing the URL altogether from the specification and got the following:

22612 [ZAP-Import-OpenAPI-1] WARN  org.zaproxy.zap.extension.openapi.converter.swagger.SwaggerConverter - Failed to build/normalise the API URL using Server URL: /
java.lang.IllegalArgumentException: The scheme must not be null.
	at org.zaproxy.zap.extension.openapi.converter.swagger.UriBuilder.validateNotNull(UriBuilder.java:279) ~[openapi-beta-19.zap:?]
	at org.zaproxy.zap.extension.openapi.converter.swagger.UriBuilder.build(UriBuilder.java:252) ~[openapi-beta-19.zap:?]
	at org.zaproxy.zap.extension.openapi.converter.swagger.SwaggerConverter.createApiUrls(SwaggerConverter.java:259) [openapi-beta-19.zap:?]
	at org.zaproxy.zap.extension.openapi.converter.swagger.SwaggerConverter.readOpenAPISpec(SwaggerConverter.java:182) [openapi-beta-19.zap:?]
	at org.zaproxy.zap.extension.openapi.converter.swagger.SwaggerConverter.getRequestModels(SwaggerConverter.java:159) [openapi-beta-19.zap:?]
	at org.zaproxy.zap.extension.openapi.ExtensionOpenApi$1.run(ExtensionOpenApi.java:289) [openapi-beta-19.zap:?]
22612 [ZAP-Import-OpenAPI-1] WARN  org.zaproxy.zap.extension.openapi.ExtensionOpenApi - Unable to obtain any server URL from the definition.
org.zaproxy.zap.extension.openapi.converter.swagger.SwaggerException: Unable to obtain any server URL from the definition.
	at org.zaproxy.zap.extension.openapi.converter.swagger.SwaggerConverter.createApiUrls(SwaggerConverter.java:272) ~[openapi-beta-19.zap:?]
	at org.zaproxy.zap.extension.openapi.converter.swagger.SwaggerConverter.readOpenAPISpec(SwaggerConverter.java:182) ~[openapi-beta-19.zap:?]
	at org.zaproxy.zap.extension.openapi.converter.swagger.SwaggerConverter.getRequestModels(SwaggerConverter.java:159) ~[openapi-beta-19.zap:?]
	at org.zaproxy.zap.extension.openapi.ExtensionOpenApi$1.run(ExtensionOpenApi.java:289) [openapi-beta-19.zap:?]

Finally, replacing localhost with the correct endpoint host-name does run correctly. But, since the host changes often, it should be obtained by the configuration, not the specification. Or is this a wrong assumption?

Thank you.

Sticcia avatar Jul 05 '21 10:07 Sticcia

We are using the following Python script in order to use ZAP https://github.com/zaproxy/zaproxy/blob/main/docker/zap-api-scan.py

And we use the following flag to set the hostname -O the hostname to override in the (remote) OpenAPI spec

There is OpenAPI add-on to ZAP that seem to expose openapitargeturl that might support the scenario that you described in the bug: https://www.zaproxy.org/docs/desktop/addons/openapi-support/

We need to do some investigation on how to expose that setting

stishkin avatar Jul 06 '21 17:07 stishkin

I don't see why the -O parameter will only override if targeted against a remote specification and not with a path to a local file. I created a bug on the ZAP repository: https://github.com/zaproxy/zaproxy/issues/6673.

Sticcia avatar Jul 07 '21 11:07 Sticcia

zaproxy/zaproxy#6673

got closed as dup of

zaproxy/zaproxy#5510

stishkin avatar Jul 09 '21 20:07 stishkin