Skip to content

fix: don't allow credentials for the wildcard CORS fallback#1

Merged
devthedevil merged 1 commit into
mainfrom
fix/cors-wildcard-credentials
Jul 7, 2026
Merged

fix: don't allow credentials for the wildcard CORS fallback#1
devthedevil merged 1 commit into
mainfrom
fix/cors-wildcard-credentials

Conversation

@devthedevil

Copy link
Copy Markdown
Owner

Problem

server.py registers CORSMiddleware with allow_credentials=True unconditionally:

def _cors_origins() -> list[str]:
    try:
        return get_settings().cors_origins
    except RuntimeError:
        return ["*"]

app.add_middleware(
    CORSMiddleware,
    allow_origins=_cors_origins(),
    allow_credentials=True,
    ...
)

The "*" fallback fires whenever ANTHROPIC_API_KEY isn't set at import time — realistically, a misconfigured deployment rather than just tests (the comment says "e.g. during tests" but nothing stops this from being the live prod config if the env var is missing).

Wildcard origin + allow_credentials=True is an unsafe combination: browsers refuse a literal * on a credentialed response, so CORS middlewares — including Starlette's, which this app uses — work around that by reflecting back whatever Origin header the request sent instead of a literal *. That means when this fallback is active, any site can have its origin accepted and make credentialed cross-origin requests, which defeats CORS entirely for that path.

Fix

Extracted the credentials decision into a small, directly-testable function:

def _allow_credentials_for(origins: list[str]) -> bool:
    return "*" not in origins

Credentials are now only enabled when explicit, non-wildcard origins are configured. No behavior change for the documented/normal setup (CORS_ORIGINS set to real origins in .env) — this only tightens the unsafe fallback path.

Testing

  • Added test_wildcard_origin_disallows_credentials and test_explicit_origins_allow_credentials, unit-testing the new function directly (avoids needing to re-import the module under different env configs just to exercise the fallback branch through TestClient).
  • Full suite: ruff check clean, pytest 25/25 passing locally.

app.add_middleware() was configured with allow_credentials=True
regardless of which origins were resolved, including the "*" fallback
used when ANTHROPIC_API_KEY isn't set at import time (e.g. a
misconfigured deployment). Wildcard origin + credentials is an unsafe
combination: browsers refuse a literal "*" on a credentialed response,
so CORS middlewares (including Starlette's) work around that by
reflecting back whatever Origin header the request sent — meaning any
site could get its origin accepted and make credentialed requests,
defeating CORS entirely for that fallback path.

Extracts the credentials decision into _allow_credentials_for(), which
only returns True for an explicit, non-wildcard origin list, and adds
direct unit tests for both branches. No behavior change for the
documented/normal setup (CORS_ORIGINS set to real origins).
@devthedevil
devthedevil merged commit 084bdf5 into main Jul 7, 2026
2 checks passed
@devthedevil
devthedevil deleted the fix/cors-wildcard-credentials branch July 7, 2026 00:24
devthedevil added a commit that referenced this pull request Jul 22, 2026
fix: don't allow credentials for the wildcard CORS fallback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant