Medium severity

How to fix a wildcard (*) CORS policy

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.

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.

How to check

  1. 01Open DevTools → Network → find a request to your API.
  2. 02Look at Response Headers: `access-control-allow-origin`.
  3. 03`*` means any origin; a specific domain is fine; missing means browsers default to same-origin only.
  4. 04Also check `access-control-allow-credentials` — if both are true for the same endpoint, that is a misconfiguration.

Or let SafeToShip check it for you in 60 seconds:

How to fix it

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 });
}

Generic

For public data endpoints with no auth, wildcard is OK. For everything else, reflect from an allowlist. Add `Vary: Origin` for caching.

Access-Control-Allow-Origin: https://app.example.com
Vary: Origin

AI prompt

Copy-paste into your AI tool

Paste this prompt into Cursor, Lovable, Bolt, v0, or Claude Code and it will walk through the fix for your specific codebase.

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.

Scan your site for this and 50+ other issues

Free scan. Results in 60 seconds. No account required.