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:
- 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.
- 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.
Summary
owasp-no-credentials-in-urltests parameter names with(
openapi/linter/rules/owasp_no_credentials_in_url.go). That is a case-insensitive, unanchored substring match, carried over from Spectral'sowasp:api2:2023-no-credentials-in-url, applied to everypathandqueryparameter name. So a path parameter calledsecretPath(the storage path of a secret in a secrets-manager API, not a credential) is reported as an error, and so aretokenIdandmySecretPath. 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(ordisabled: true/ a lower severity for the rule inlint.yaml), all of which switch the check off for the whole document, including the parameters it should catch.Reproduction
Same result with the name changed to
secret_path,tokenIdormySecretPath.openapibuilt withgo install github.com/speakeasy-api/openapi/cmd/openapi@latest(v0.0.0-20260826005500-83ebf39fa45e).Suggested fix
Either would help; both would be better:
_,-and camelCase boundaries and flag it when the credential word is the head (last) token:clientSecret,access_token,api-key,passwordare credentials, whilesecretPath,tokenId,secretNamename a path, an id, a name. A cheaper variant keeps the regex and skips names ending in a non-credential suffix such asPath,Name,Id,Url,Type.x-extension on the parameter listing rule IDs to ignore, or a per-ruleexcludelist of JSON paths inlint.yaml, would both do.I can put a PR together for (1) if you'd take it.