MCPSafe.io
RegistryThreatsMethodologyDocsPricingScanSign in
MCPSafe.io

Security checks for MCP servers — public packages and private repos, fast or deep.

Legal

Privacy PolicyCookie PolicyTerms of ServiceSecurity disclosure

Resources

State of MCP SecuritySupportSystem statusMade in Germany 🇩🇪

© 2026 MCPSafe. All rights reserved.

GDPR — Privacy Policy
← Threat Catalog

Configuration & Environment

CORS wildcard origin with credentials

MEDIUMCWE: CWE-942Rule: MCP-273

MCP server sets `Access-Control-Allow-Origin: *` (or reflects the request `Origin` header) AND `Access-Control-Allow-Credentials: true` — combo creates an effective CSRF amplifier on every state-changing route.

What it is

Browsers reject the literal `*` + credentials combo, but reflecting `req.headers.origin` and serving credentials is functionally equivalent and widely accepted. Either pattern means: any website the user visits can issue authenticated requests to your MCP server, with the user's cookies/auth headers attached. The right defense is an explicit allowlist of trusted origins, OR drop credentials and use bearer tokens in the `Authorization` header.

Why it matters for MCP

MCP servers exposing HTTP transport on a public domain are a CSRF target — an attacker's web page can call destructive MCP tools through the user's browser. Permissive CORS makes it trivial. The CSA / OWASP "MCP Top 10" calls this out as a common misconfiguration; this rule closes the gap.

Vulnerable example

example.js
1
import express from "express";
2
import cors from "cors";
3
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
5
const app = express();
6
const mcp = new McpServer({ name: "my-mcp", version: "1.0.0" });
7
8
// Wildcard origin + credentials = CSRF amplifier.
9
app.use(cors({
10
    origin: "*",
11
    credentials: true,
12
}));
13
14
// Equally bad: reflecting Origin header.
15
app.use(cors({
16
    origin: (req) => req.headers.origin,
17
    credentials: true,
18
}));

Secure example

example.js
1
import express from "express";
2
import cors from "cors";
3
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
5
const app = express();
6
const mcp = new McpServer({ name: "my-mcp", version: "1.0.0" });
7
8
// Explicit allowlist + credentials = safe.
9
app.use(cors({
10
    origin: ["https://app.example.com", "https://admin.example.com"],
11
    credentials: true,
12
}));

How MCPSafe detects this

Per-occurrence in MCP-server-context files. Fires when CORS configuration sets BOTH (1) wildcard origin (`origin: "*"`) or reflecting origin (`origin: req.headers.origin`, `origin: true` in `cors()` — which mirrors the request) AND (2) credentials enabled (`credentials: true` / `allow_credentials=True` / `Access-Control-Allow-Credentials: true` header) in the same configuration object or call. Frameworks supported: Express `cors({...})` middleware, FastAPI `add_middleware(CORSMiddleware, ...)`, Flask-CORS `CORS(app, ...)`, manual header sets (`res.setHeader` / `response.headers[...]`).

See the full threat catalog for every documented detection.

Further reading

  • OWASP — CORS Misconfigurations
  • PortSwigger — Exploiting CORS Misconfigurations
  • CWE-942: Permissive Cross-domain Policy

Scan an MCP server for this issue

MCPSafe runs this check — and every other rule in the catalog — on any MCP server you paste in.

Scan now