{"slug": "why-cursor-keeps-generating-wildcard-cors-headers-in-your-api", "title": "Why Cursor Keeps Generating Wildcard CORS Headers in Your API", "summary": "A developer discovered that the AI code editor Cursor fixed a CORS error in their side project by generating middleware that uses origin reflection, a pattern that echoes back any Origin header sent by the requester. This creates a security vulnerability (CWE-942) that allows any website to read authenticated API responses by sending a matching Origin header. The developer warns that AI editors reproduce this pattern because training data skews toward the fastest fix that works everywhere, and recommends replacing origin reflection with an explicit allowlist of trusted domains.", "body_md": "I hit a CORS error in a side project last week. Frontend on one port, API on another, browser blocking the request. I asked Cursor to fix it, and it did, instantly. The error went away. I moved on to the actual feature I was building.\n\nThree days later I was reading through the generated middleware for something unrelated and noticed what \"fixed\" actually meant. It hadn't allowlisted my frontend's origin. It had told the server to accept requests from anywhere, with cookies attached.\n\nThat's the trade AI editors make by default. You ask for the error to go away, and the fastest way to make a CORS error go away is to stop checking who's asking.\n\nThe pattern shows up as origin reflection, not a plain wildcard. A bare `Access-Control-Allow-Origin: *`\n\ncombined with `Access-Control-Allow-Credentials: true`\n\nactually gets rejected by the browser, so tutorials work around that by echoing back whatever Origin header the request sent. That workaround is the vulnerability.\n\n``` js\n// ❌ CWE-942: Permissive Cross-domain Policy\napp.use((req, res, next) => {\n  res.header('Access-Control-Allow-Origin', req.headers.origin);\n  res.header('Access-Control-Allow-Credentials', 'true');\n  res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE');\n  next();\n});\n```\n\n`req.headers.origin`\n\nis a value the requester controls. A page hosted on `evil-site.com`\n\nsends `Origin: evil-site.com`\n\n, the server echoes it straight back, and the browser sees a match. Credentials are allowed, so the victim's session cookie rides along. Any authenticated GET or POST your API exposes is now readable and callable from a page the victim never meant to trust.\n\nOrigin reflection survives in training data because it's the fastest fix that makes a CORS error disappear in local development, and almost every public snippet optimizes for that. Stack Overflow answers, boilerplate repos, and \"quick fix\" gists all reach for the same three lines because they work identically whether you're testing on `localhost:3000`\n\n, `localhost:5173`\n\n, or a Vercel preview URL. Nobody has to think about which origins are actually supposed to be allowed.\n\nAn explicit allowlist requires knowing your production frontend's domain ahead of time, which isn't information available in an isolated code snippet. So the training data skews toward the version that works everywhere and restricts nothing. AI editors reproduce that pattern faithfully, and it ships because it passes every test a developer actually runs before deploying.\n\nReplace origin reflection with a fixed list of domains you actually trust, checked explicitly against each incoming request.\n\n``` js\n// ✅ Explicit allowlist, no reflection\nconst allowedOrigins = [\n  'https://app.example.com',\n  'https://admin.example.com'\n];\n\napp.use(cors({\n  origin: (origin, callback) => {\n    if (!origin || allowedOrigins.includes(origin)) {\n      callback(null, true);\n    } else {\n      callback(new Error('Not allowed by CORS'));\n    }\n  },\n  credentials: true\n}));\n```\n\nPython/Flask version of the same fix:\n\n``` python\nfrom flask_cors import CORS\n\nCORS(\n    app,\n    origins=[\"https://app.example.com\", \"https://admin.example.com\"],\n    supports_credentials=True\n)\n```\n\nFor local development, add `localhost`\n\nports to the allowlist explicitly rather than falling back to a wildcard or reflection \"just for now.\" Environment variables work well here: one allowlist for dev, a locked-down one for production, both explicit.\n\n**Q: Is Access-Control-Allow-Origin: * with credentials actually dangerous?**\n\n**Q: Does a CORS allowlist replace authentication?**\n\nA: No. CORS controls which browser-based origins can read a response, not who's authorized to call the endpoint. You still need real auth checks; CORS is a second layer that stops the browser from letting an untrusted page use a victim's session.\n\n**Q: How do I check my API for this right now?**\n\nA: Look for any CORS middleware where the `Access-Control-Allow-Origin`\n\nvalue comes from a request header instead of a fixed list. If you see `req.headers.origin`\n\nor `req.get('origin')`\n\nwritten straight into the response, that's the pattern.\n\nI've been running [SafeWeave](https://tinyurl.com/23dknpup) for this. It hooks into Cursor and Claude Code as an MCP server and flags these patterns before I move on. Even a basic pre-commit hook with semgrep and gitleaks will catch most of what's in this post, the important thing is catching it early, whatever tool you use.", "url": "https://wpnews.pro/news/why-cursor-keeps-generating-wildcard-cors-headers-in-your-api", "canonical_source": "https://dev.to/c_k_fb750e731394/why-cursor-keeps-generating-wildcard-cors-headers-in-your-api-33ii", "published_at": "2026-07-24 16:49:36+00:00", "updated_at": "2026-07-24 17:02:20.398006+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "ai-safety"], "entities": ["Cursor", "CWE-942", "Stack Overflow", "Vercel", "Flask"], "alternates": {"html": "https://wpnews.pro/news/why-cursor-keeps-generating-wildcard-cors-headers-in-your-api", "markdown": "https://wpnews.pro/news/why-cursor-keeps-generating-wildcard-cors-headers-in-your-api.md", "text": "https://wpnews.pro/news/why-cursor-keeps-generating-wildcard-cors-headers-in-your-api.txt", "jsonld": "https://wpnews.pro/news/why-cursor-keeps-generating-wildcard-cors-headers-in-your-api.jsonld"}}