CORS allows all origins on Next.js
Your API responds with `Access-Control-Allow-Origin: *`, which allows any website to call your endpoints. For public APIs that do not handle authentication, this is intentional and fine. For any endpoint that relies on session cookies or auth tokens, it is a bug. Fix it by setting the header to a specific allowed origin, or a narrow allowlist — and remove `Access-Control-Allow-Credentials: true` if you do not actually use credentialed requests.
The fix for Next.js
Next.js Route Handlers
Read the request Origin header; reflect it if it is in your allowlist.
const ALLOWED = ['https://app.example.com', 'https://example.com'];
export async function GET(req: Request) {
const origin = req.headers.get('origin');
const headers = new Headers({ 'content-type': 'application/json' });
if (origin && ALLOWED.includes(origin)) {
headers.set('Access-Control-Allow-Origin', origin);
headers.set('Vary', 'Origin');
}
return new Response(JSON.stringify({ ok: true }), { headers });
}Why it matters
CORS is defense against cross-origin attacks. A wildcard means any malicious site can call your API from a user's browser. If you set both `Allow-Origin: *` and `Allow-Credentials: true` (which browsers reject, but proxies sometimes rewrite), you have a serious CSRF-equivalent.
Confirm the fix worked
Scan your Next.js site to confirm this finding is gone.
AI prompt
Apply across your codebase
Paste this into Cursor, Lovable, Bolt, v0, or Claude Code.
My API responds with `Access-Control-Allow-Origin: *`. For each of my API endpoints, tell me whether it is meant to be public (in which case the wildcard is fine) or meant to serve authenticated user data (in which case it is a bug). For the authenticated ones, implement an allowlist of my known frontend origins and reflect the Origin header when it matches. Add `Vary: Origin` for correct caching.FAQ
Frequently asked questions
- Can I just use credentials: "include" with wildcard?
- No — browsers reject that combination. If your fetch uses `credentials: "include"`, you must set a specific origin, not *.
- What about preflight (OPTIONS) requests?
- Preflight responses also need the allow-origin header, plus `Access-Control-Allow-Methods` and `Access-Control-Allow-Headers`. Handle OPTIONS explicitly in your route handler.
Related fix guides
Fix these too
CORS credentials misconfiguration
Setting both Allow-Origin: * and Allow-Credentials: true is a dangerous misconfiguration. Here is why browsers block it and how to fix it correctly.
Read moreMissing CSP header
A missing Content-Security-Policy header lets attackers inject scripts into your site. Here is what CSP does, why you need it, and how to add it in Next.js, Vercel, and Supabase apps.
Read moreFree tools