speakeasy-api / speakeasy-api/openapi

owasp-no-credentials-in-url flags any parameter whose name merely contains "secret" or "token" (e.g. secretPath), with no per-parameter escape

Open
#251 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
276
Forks
18
Avg merge
3d 16h
Merged PRs (30d)
2

Description

Summary

owasp-no-credentials-in-url tests parameter names with

regexp.MustCompile(`(?i)^.*(client_?secret|token|access_?token|refresh_?token|id_?token|password|secret|api-?key).*$`)

(openapi/linter/rules/owasp_no_credentials_in_url.go). That is a case-insensitive, unanchored substring match, carried over from Spectral's owasp:api2:2023-no-credentials-in-url, applied to every path and query parameter name. So a path parameter called secretPath (the storage path of a secret in a secrets-manager API, not a credential) is reported as an error, and so are tokenId and mySecretPath. Any domain whose nouns include "secret" or "token" trips it on names that carry no credential at all.

There is no per-parameter escape. The only ways to make the finding go away are --disable owasp-no-credentials-in-url (or disabled: true / a lower severity for the rule in lint.yaml), all of which switch the check off for the whole document, including the parameters it should catch.

Reproduction

openapi: 3.1.0
info: { title: t, version: "1" }
paths:
  /files/{secretPath}:
    get:
      parameters: [{ name: secretPath, in: path, required: true, schema: { type: string } }]
      responses: { "200": { description: ok } }
$ openapi spec lint owasp.yaml | grep credentials
 6:28 error   owasp-no-credentials-in-url      URL parameter `secretPath` appears to contain credentials - avoid passing sensitive data in URLs
$ openapi spec lint --disable owasp-no-credentials-in-url owasp.yaml | grep -c credentials
0

Same result with the name changed to secret_path, tokenId or mySecretPath. openapi built with go install github.com/speakeasy-api/openapi/cmd/openapi@latest (v0.0.0-20260826005500-83ebf39fa45e).

Suggested fix

Either would help; both would be better:

  1. Token-aware matching. Split the name on _, - and camelCase boundaries and flag it when the credential word is the head (last) token: clientSecret, access_token, api-key, password are credentials, while secretPath, tokenId, secretName name a path, an id, a name. A cheaper variant keeps the regex and skips names ending in a non-credential suffix such as Path, Name, Id, Url, Type.
  2. A per-parameter suppression, so a reviewed false positive can be silenced in place instead of turning the rule off document-wide. An x- extension on the parameter listing rule IDs to ignore, or a per-rule exclude list of JSON paths in lint.yaml, would both do.

I can put a PR together for (1) if you'd take it.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with openapi/linter/rules/owasp_no_credentials_in_url.go and run the YAML reproduction with the linter command shown. Trace how parameter names are matched and how rule configuration is applied. Done means reviewed false positives such as secretPath no longer trigger while credential-like names remain covered, with the chosen per-parameter suppression behavior defined and verified.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
api, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.