Linter rulesOpenAPIprivacy/no-credentials-in-url

privacy/no-credentials-in-url

Since 0.11.0

This rule reports passwords, tokens, API keys and other credentials passed in path or query parameters, and API keys that a security scheme sends in the query string.

Rule Details

URLs are not secret. Servers, load balancers and proxies log them, browsers keep them in their history and bookmarks, and they leak to other sites in the Referer header. A credential in a URL is a credential in all of these places (OWASP API Security Top 10 API2:2023 Broken Authentication, CWE-598).

The rule looks at every in: path and in: query parameter, including the parameters of components.parameters, and reports:

  • a parameter whose name contains a credential term, in any naming convention: password, passwd, secret, token (access_token, resetToken, …), api key, private key, session id, auth, credentials, otp, pin, cvv, and a few more;
  • a parameter whose schema has format: password;
  • an object parameter (style: form, deepObject or content) with such a property, since the serialization puts property names and values in the URL;
  • an apiKey security scheme with in: query.

A term matches whole words of the name: nextPageToken, continuation_token and author are not reported, pinCode is. Names that describe a credential instead of holding it, where the term is followed by id, name, type, status, count, expiry and the like (secret_name, signing_key_id, token_type_hint), are not reported; session_id is. The OAuth 2.0 authorization_code, which the redirect carries in the query by design, is not reported either.

Configuration

An object with two optional properties:

  • allow: parameter and property names that are never reported, compared case-insensitively.
  • terms: more names to report, in any naming convention (magicLink also finds magic_link).
commands:
  lint:
    rules:
      privacy/no-credentials-in-url:
        - error
        - allow: [token]
          terms: [magicLink]

Examples

Good. The token travels in the Authorization header.

components:
  securitySchemes:
    bearer:
      type: http
      scheme: bearer

Bad. Every request URL contains the key.

paths:
  /reports:
    get:
      parameters:
        - name: api_key
          in: query
          schema:
            type: string

When Not to Use It

When a URL is meant to be a short-lived capability (a pre-signed download link, a password reset link sent by e-mail), disable the rule on that parameter with x-apigenie-lint-disable.

Compatibility

This rule is compatible with all OpenAPI 3.x versions.

Related rules

Further reading