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.cors.fastapi-wildcard-credentials

FastAPI CORS allows any origin with credentials.

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

Starlette's CORSMiddleware is configured with a wildcard origin (allow_origins=["*"] or allow_origin_regex=".*") together with allow_credentials=True. The CORS spec forbids Access-Control-Allow-Origin: * alongside Access-Control-Allow-Credentials: true, so Starlette silently reflects the caller's Origin instead, turning the wildcard into "allow every site" for credentialed requests. Any website can then read authenticated responses, leaking cookies, session and OAuth tokens cross-origin (CWE-942).

Credentialed CORS needs an explicit allow-list of trusted origins, e.g. allow_origins=["https://app.example.com"], allow_credentials=True. If the endpoint is genuinely public, drop credentials: allow_origins=["*"], allow_credentials=False.

VULNERABLE
vulnerable.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

# ruleid: auth.py.cors.fastapi-wildcard-credentials
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Argument order reversed: credentials before origins.
# ruleid: auth.py.cors.fastapi-wildcard-credentials
app.add_middleware(
    CORSMiddleware,
    allow_credentials=True,
    allow_origins=["*"],
)

# Wildcard expressed as a regex.
# ruleid: auth.py.cors.fastapi-wildcard-credentials
app.add_middleware(
    CORSMiddleware,
    allow_origin_regex=".*",
    allow_credentials=True,
)

# Direct instantiation form.
# ruleid: auth.py.cors.fastapi-wildcard-credentials
middleware = CORSMiddleware(
    app,
    allow_origins=["*"],
    allow_credentials=True,
)
SAFE
safe.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

# Explicit allow-list with credentials is the correct pattern.
# ok: auth.py.cors.fastapi-wildcard-credentials
app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://app.example.com"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Wildcard origin is fine when credentials are disabled.
# ok: auth.py.cors.fastapi-wildcard-credentials
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=False,
)

# Wildcard without any credentials argument (defaults to False).
# ok: auth.py.cors.fastapi-wildcard-credentials
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
)

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.cors.fastapi-wildcard-credentials -- <reason>

References

https://www.starlette.io/middleware/#corsmiddleware ↗https://fastapi.tiangolo.com/tutorial/cors/ ↗https://cwe.mitre.org/data/definitions/942.html ↗