Handing statements to anyone’s messenger
Watch it happen
Alice visits Mallory’s shop. Mallory’s messenger takes Alice’s badge to the bank, and the teller hands the statement to any messenger.
Alice is logged in to the bank, so her browser holds a badge. She walks in through the front door.
In bank terms and app terms
| In the bank | In your app |
|---|---|
SameSite=None cookies) | |
Access-Control-Allow-Origin | |
*, or copying the request’s Origin header back (the dangerous one when cookies are involved) |
Are you exposed?
Your API sets Access-Control-Allow-Origin: *, or copies the incoming Origin header straight back.You turned on CORS for “everything” to make a local-dev error go away and never narrowed it. Your API relies on cookies, and also allows nullor any subdomain as an origin.
Keep a list of exact origins you trust (your own app and admin site) and only echo an origin if it is on the list. Browsers refuse a wildcard together with cookies, so don’t “fix” that error by echoing any origin back. Never allow the nullorigin.For public data that needs no login, *is fine. For anything tied to a user, use the allowlist.
What it looks like in code
// BAD: Wildcard CORS (browsers refuse "*" together with credentials, so the real exploit is reflecting the Origin header)
response.headers.set("Access-Control-Allow-Origin", "*")
response.headers.set("Access-Control-Allow-Credentials", "true")
// BAD: Reflecting the Origin header without validation
const origin = request.headers.get("Origin")
response.headers.set("Access-Control-Allow-Origin", origin)
Ask your AI tool to fix it
Paste this into Cursor, Claude, Lovable, Bolt or whatever you build with.
Audit the CORS configuration of this app. Replace any Access-Control-Allow-Origin: * or code that reflects the request Origin with an allowlist of exact origins read from an environment variable. Only send Access-Control-Allow-Credentials: true for origins on that list, never allow the "null" origin, and add Vary: Origin. Keep local development working with a localhost entry in the dev env only.Where this comes from
The facts, figures and fixes on this page were checked against these sources on 25 Oct 2026. They are linked so you can check for yourself.
- Cross-Origin Resource Sharing (CORS)MDN Web DocsBrowser blocks wildcard with cookies; allowlist origin plus Vary: Origin
- Access-Control-Allow-Origin headerMDN Web Docs* only for public data; never allow the null origin; check Origin against a list
- Cross-origin resource sharing (CORS)PortSwigger Web Security AcademyReflected Origin and null origin let a malicious site read a logged-in user's data
- Set-Cookie header (SameSite)MDN Web DocsCookies go cross-site only with SameSite=None; Lax default is browser-dependent
Spot a mistake or something out of date? Report a correction · How these guides are made and checked
The free, open-source scanner checks for most of the problems in these guides.