Slide 4 of 28
Part 1 · What Is It?Slide 4
Slide 4 · The Dangerous One
CORS — the misconfiguration that lets any website read your users’ data.
Not Access-Control-Allow-Origin: *. The dangerous pattern is reflecting the caller’s origin and allowing credentials.
What CORS is for

Browsers block JavaScript on one site from reading responses from a different site — the Same-Origin Policy. CORS is the mechanism that allows an API to explicitly opt in to cross-origin access for trusted sites. The API responds with HTTP headers telling the browser which origins are permitted.

Safe (restrictive)
Access-Control-Allow-Origin: https://app.yourcompany.com
Only your own frontend can make cross-origin requests to the API
Browser rejects requests from any other origin — attacker’s site included
Dangerous (misconfigured)
Access-Control-Allow-Origin: [reflects caller’s Origin header]
Access-Control-Allow-Credentials: true
Any site can make authenticated requests and read the response. Attacker’s site included.
WHY
Why developers misconfigure CORS

During development: the frontend is at localhost:3000, the API is at localhost:8000. The developer adds Access-Control-Allow-Origin: * to stop browser errors. It works, it ships to production, it stays.

A slightly more dangerous pattern: the developer wants to support multiple frontends, so they write code that reads the incoming Origin header and reflects it back in the response. Every origin is “allowed” — including the attacker’s. When combined with Access-Control-Allow-Credentials: true, this allows any website to make authenticated API calls and read the responses.

The exploit: An attacker hosts a page at attacker.com. The page uses JavaScript to make a cross-origin request to api.yourcompany.com with the user’s cookies. The API reflects the attacker’s origin and allows credentials. The browser sends the request with the user’s cookies. The attacker’s page reads the full API response — including the user’s account data, session info, or any other authenticated resource.
← Back Verbose errors →