v0.14 is out: a mobile auth pack for Swift/iOS and Android, catching insecure token storage, cleartext traffic, and OAuth in embedded WebViews. Read more →
HIGH AI PREVALENCE: HIGH auth.py.oauth.hardcoded-client-secret

An OAuth client secret is passed as a string literal to the OAuth client.

Why AI tools produce this: AI coding tools generate this anti-pattern by default, it appears in a large share of AI-written auth code.

Why this matters

Committed to source control it is one search away from compromise, letting an attacker impersonate your application at the authorization server and exchange codes for tokens (CWE-798). AI-generated OAuth snippets inline the secret to make the example run.

Read it from the environment or a secret store instead, e.g. client_secret=os.environ["OAUTH_CLIENT_SECRET"].

VULNERABLE
vulnerable.py
from authlib.integrations.requests_client import OAuth2Session

def make_client():
    # ruleid: auth.py.oauth.hardcoded-client-secret
    session = OAuth2Session("my-client-id", "s3cr3t-client-value", scope="openid")
    return session

def register(oauth):
    # ruleid: auth.py.oauth.hardcoded-client-secret
    oauth.register(name="google", client_id="abc", client_secret="hardcoded-secret-xyz")
SAFE
safe.py
import os
from authlib.integrations.requests_client import OAuth2Session

def make_client():
    # ok: secret from the environment
    session = OAuth2Session("my-client-id", os.environ["OAUTH_CLIENT_SECRET"], scope="openid")
    return session

def register(oauth):
    # ok: secret from settings/env
    oauth.register(name="google", client_id="abc", client_secret=os.getenv("GOOGLE_SECRET"))

Suppressing this rule

If a finding is a genuine false positive, scope the suppression to the exact line and leave a reason, never disable the rule project-wide. Disable directives are line-scoped by design.

# oauthlint-disable-next-line auth.py.oauth.hardcoded-client-secret -- <reason>

References

https://docs.authlib.org/en/latest/client/oauth2.html ↗https://cwe.mitre.org/data/definitions/798.html ↗