PROCYON

PRC004 — Server URL does not use TLS

Severityhigh
OWASP API Security Top 10API8:2023 Security Misconfiguration

What it catches

A server URL that uses http://, at any level the spec declares servers: the whole spec, a path, or an operation.

  • Local development servers are exempt: localhost, 127.0.0.1 (any 127.x.x.x) and [::1].
  • Relative URLs (/v1) are not reported: they inherit the scheme of wherever the spec is served from.
  • Swagger 2.0: schemes (of the spec or of an operation) are checked with host. A spec with no host has no server URL, so its schemes are not checked.
  • A URL built from variables ({scheme}://api.example.com) is checked with every value its variables allow (their enum, or their default). If any of them makes it http://, it is reported. The scheme and the host are checked separately, each with only the variables that appear in it. If a part has more than 1024 combinations, Procyon cannot check them all and reports the server anyway: a security check fails closed.

Why it matters

Requests to an http:// server travel unencrypted. Anyone on the network path (public Wi-Fi, a compromised router, a misbehaving proxy) can read them, including passwords, API keys and session tokens, and can change requests and responses without either side noticing.

Clients, SDKs and API gateways generated from the spec use these URLs, so a plain-text URL in the spec tends to end up in real traffic.

How to fix it

Use https://:

servers:
  - url: https://api.example.com

For a templated URL, remove http from the variable's enum.

How to ignore it

If the finding is fine on purpose, write an x-procyon-ignore on the server (in a Swagger 2.0 spec, the root), with the reason. The finding is still reported, under Ignored, and no longer fails the run. See ignoring a finding.

servers:
  - url: http://api.internal.example.com
    x-procyon-ignore:
      - rule: PRC004
        reason: "Internal network only; TLS ends at the sidecar"

Examples

Reported:

servers:
  - url: http://api.example.com
  - url: "{scheme}://api.example.com"
    variables:
      scheme:
        default: https
        enum: [https, http]

Not reported:

servers:
  - url: https://api.example.com
  - url: http://localhost:8080
  - url: /v1