Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OWASP ruleset doesn't seem to work with swagger 2 appspecs as of v0.7.0 #525

Open
TheTeaCat opened this issue Jul 19, 2024 · 1 comment
Open
Labels
documentation Improvements or additions to documentation

Comments

@TheTeaCat
Copy link
Contributor

TheTeaCat commented Jul 19, 2024

The out-of-the-box OWASP ruleset doesn't seem to flag anything up in swagger 2 specs as of v0.7.0. For example, the following swagger 2 spec yields no findings (when I run a spectral report, vacuum just writes out null):

Swagger 2 specification
swagger: '2.0'
info:
  title: My API
  version: '1.0.0'
paths:
  /profile:
    get:
      responses:
        '200':
          description: OK
        '400':
          description: Bad Request
        '401':
          description: Unauthorized
        '500':
          description: Internal Server Error

However, if I convert it to OpenAPI 3.0.1 at editor.swagger.io:

OpenAPI 3.0.1 equivalent
openapi: 3.0.1
info:
  title: My API
  version: 1.0.0
servers:
- url: /
paths:
  /profile:
    get:
      responses:
        "200":
          description: OK
          content: {}
        "400":
          description: Bad Request
          content: {}
        "401":
          description: Unauthorized
          content: {}
        "500":
          description: Internal Server Error
          content: {}
components: {}
x-original-swagger-version: "2.0"

Then I get all these findings:

Spectral report from the OpenAPI 3.1.0 specification
[
    {
        "code": "owasp-security-hosts-https-oas3",
        "path": [
            "servers",
            "0",
            "url"
        ],
        "message": "server URLs should use TLS (https)",
        "severity": 0,
        "range": {
            "start": {
                "line": 6,
                "character": 5
            },
            "end": {
                "line": 6,
                "character": 8
            }
        },
        "source": "swagger_converted.yaml"
    },
    {
        "code": "owasp-protection-global-safe",
        "path": [
            "paths",
            "/profile",
            "get"
        ],
        "message": "`security` was not defined for path `/profile` in method `get`",
        "severity": 3,
        "range": {
            "start": {
                "line": 9,
                "character": 5
            },
            "end": {
                "line": 9,
                "character": 8
            }
        },
        "source": "swagger_converted.yaml"
    },
    {
        "code": "owasp-define-error-responses-429",
        "path": [
            "paths",
            "/profile",
            "get",
            "responses"
        ],
        "message": "missing response code `429` for `GET`",
        "severity": 1,
        "range": {
            "start": {
                "line": 10,
                "character": 7
            },
            "end": {
                "line": 10,
                "character": 16
            }
        },
        "source": "swagger_converted.yaml"
    },
    {
        "code": "owasp-rate-limit",
        "path": [
            "paths",
            "/profile",
            "get",
            "responses",
            "200"
        ],
        "message": "response with code `200`, must contain one of the defined headers: `{X-RateLimit-Limit} {X-Rate-Limit-Limit} {RateLimit-Limit, RateLimit-Reset} {RateLimit} `",
        "severity": 0,
        "range": {
            "start": {
                "line": 11,
                "character": 9
            },
            "end": {
                "line": 11,
                "character": 12
            }
        },
        "source": "swagger_converted.yaml"
    },
    {
        "code": "owasp-rate-limit",
        "path": [
            "paths",
            "/profile",
            "get",
            "responses",
            "400"
        ],
        "message": "response with code `400`, must contain one of the defined headers: `{X-RateLimit-Limit} {X-Rate-Limit-Limit} {RateLimit-Limit, RateLimit-Reset} {RateLimit} `",
        "severity": 0,
        "range": {
            "start": {
                "line": 14,
                "character": 9
            },
            "end": {
                "line": 14,
                "character": 12
            }
        },
        "source": "swagger_converted.yaml"
    },
    {
        "code": "owasp-rate-limit",
        "path": [
            "paths",
            "/profile",
            "get",
            "responses",
            "401"
        ],
        "message": "response with code `401`, must contain one of the defined headers: `{X-RateLimit-Limit} {X-Rate-Limit-Limit} {RateLimit-Limit, RateLimit-Reset} {RateLimit} `",
        "severity": 0,
        "range": {
            "start": {
                "line": 17,
                "character": 9
            },
            "end": {
                "line": 17,
                "character": 12
            }
        },
        "source": "swagger_converted.yaml"
    },
    {
        "code": "owasp-define-error-responses-401",
        "path": [
            "paths",
            "/profile",
            "get",
            "responses",
            "401"
        ],
        "message": "missing schema for `401` response on `GET`",
        "severity": 1,
        "range": {
            "start": {
                "line": 19,
                "character": 11
            },
            "end": {
                "line": 19,
                "character": 18
            }
        },
        "source": "swagger_converted.yaml"
    },
    {
        "code": "owasp-define-error-responses-500",
        "path": [
            "paths",
            "/profile",
            "get",
            "responses",
            "500"
        ],
        "message": "missing schema for `500` response on `GET`",
        "severity": 1,
        "range": {
            "start": {
                "line": 22,
                "character": 11
            },
            "end": {
                "line": 22,
                "character": 18
            }
        },
        "source": "swagger_converted.yaml"
    }
]

The diff between v0.6.3 and v0.7.0 shows a lot of rewriting of the OWASP ruleset. There are no test cases for swagger 2 specifications. Has support for swagger 2 been dropped in this ruleset or is it lacking implementation?

@daveshanley
Copy link
Owner

When I re-built the OWASP rules, they were all written to use the programatic model, instead of using JSON path lookups (which were very slow, prone to breaking and spewed duplicate results).

The programatic model only works with OpenAPI 3+ and not swagger.

I am actually deprecating swagger support across most of the built in functions to be honest. Swagger is old and proprietary and would mean duplicating a huge amount of logic to support it.

So the short answer, expect deteriorating support for swagger and increasing accuracy and power for OpenAPI in vacuum.

@daveshanley daveshanley added the documentation Improvements or additions to documentation label Jul 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

2 participants