Skip to content

OAuth HTTP routes set CORSMiddleware(allow_origins="*") on token/register/metadata endpoints | #3563

Description

@tiagovilasboas

Static review of public source at commit 6affe5c0d358. No traffic was sent to any MCP environment.

OAuth route helpers wrap several endpoints with Starlette CORSMiddleware and a wildcard origin:

src/mcp/server/auth/routes.py:

def _cors(app: ASGIApp, allow_methods: list[str]) -> ASGIApp:
    return CORSMiddleware(
        app=app,
        allow_origins="*",
        allow_methods=allow_methods,
        allow_headers=[MCP_PROTOCOL_VERSION_HEADER],
    )

That wrapper is used for /.well-known/oauth-authorization-server, /token, and (when enabled) /register and /revoke. Wildcard ACAO is intentional for browser-based inspectors, and allow_credentials is not set here (browsers will not attach cookies under the * + credentials rule). Still, token and dynamic-registration endpoints are sensitive: a wildcard makes any future “reflect Origin + credentials” change, or a non-browser client that ignores CORS, easier to misuse.

Suggested change:

  • Keep * only on public metadata handlers.
  • For /token, /register, and /revoke, take an explicit allowed_origins list (or reuse TransportSecuritySettings.allowed_origins) and document the Inspector origin as an example allowlist entry.
  • Add a one-line comment that credentials must stay off while * remains.

Severity: low / configuration clarity and defense-in-depth. Not reported as an exploitable CORS bypass with the current header pair. No proof-of-concept.

Happy to send a focused PR if useful.

Activity

  1. added
    v2Affects the v2 line (2.x on main)
    v1Affects the v1.x maintenance line
    on Sep 22, 2026
  2. maxisbey commented on Oct 6, 2026

    @maxisbey
    Contributor

    Thanks for the review. I'm going to close this as not planned.

    The wildcard is deliberate, so that browser-based clients can reach these endpoints. As you note, credentials are off, so no cookies are attached. The endpoints authenticate from what's in the request itself (client credentials, PKCE), so CORS isn't what protects them. The TypeScript SDK's auth handlers do the same.

    If you find a way to actually misuse this, please report it through our security policy.

    AI Disclaimer


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    v1Affects the v1.x maintenance linev2Affects the v2 line (2.x on main)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions