This article presents a hands-on CORS misconfiguration lab that demonstrates how servers reflecting the Origin header while setting Access-Control-Allow-Credentials: true create a critical vulnerability. The flaw allows attackers to make authenticated requests to a victim's account and read sensitive responses like auth tokens. Understanding this misconfiguration is essential because it is among the most common CORS findings in real-world bug-bounty programs and directly enables account takeover.
- The dangerous CORS combination explainedWhen a server echoes back whatever Origin header it receives into the Access-Control-Allow-Origin response header and also sets Access-Control-Allow-Credentials: true, it tells the browser that every website is trusted to make authenticated requests and read responses. This pair is described as the worst CORS combination because it effectively disables the same-origin policy for all origins simultaneously.
- How the attack executes step by stepAn attacker creates a page that sends a fetch request to the victim's bank endpoint (/me) with credentials included. Because the server reflects the attacker's origin and permits credentials, the victim's session cookie automatically attaches to the request. The browser then allows the attacker's script to read the JSON response, from which the auth token can be extracted and submitted.
- Why browsers enforce the misconfigurationCORS validation happens on the client side based on what the server declares in response headers. When a server reflects the requester's origin into Allow-Origin paired with Allow-Credentials: true, the browser interprets this as explicit permission from the server that this origin is trustworthy, so it allows the response to be read by that origin's script.
- Real-world prevalence and impactOrigin-reflection with credentials is described as one of the most common CORS findings in bug-bounty programs because developers often use reflection as a quick fix to enable cross-origin functionality. The article maps this issue to OWASP's Security Misconfiguration (A05) category and notes it leads directly to account takeover when endpoints return tokens or personal data.
- Correct allowlist implementationThe defense requires maintaining a strict allowlist of explicitly trusted origins and only echoing the Allow-Origin header when the request's origin matches an entry on that list. Access-Control-Allow-Credentials: true must only ever accompany a single trusted origin from this list, never a reflected origin or wildcard.
- Detection technique for testersA practical way to identify this vulnerability is to send requests with Origin headers set to random or unregistered domains. If the server reflects these arbitrary origins into Access-Control-Allow-Origin alongside Allow-Credentials: true, the misconfiguration has been found.
- Additional defensive measuresBeyond strict allowlisting, the article recommends preferring same-site cookies and short-lived tokens so that if a response is leaked through this vulnerability, the leaked credentials have limited time-window utility. It also emphasizes that the Origin header should only be used to identify who is asking, not to determine authorization.
Bottom line: Never reflect the Origin header in Access-Control-Allow-Origin when allowing credentials; instead maintain a strict allowlist of trusted origins and only echo Allow-Origin for origins explicitly on that list. This single rule prevents account takeover attacks that exploit CORS misconfiguration to steal authenticated users' tokens and sensitive data.
Origin a request carries back into Access-Control-Allow-Origin, and it also sends Access-Control-Allow-Credentials: true. That pair is the worst CORS combination there is: it tells the browser that any website is allowed to make authenticated requests and read the response.📋 In this walkthrough
What this lab teaches
CORS controls which other origins a browser will let read a cross-site response. Done right, it is an allowlist. Done wrong — reflecting the caller's origin and allowing credentials — it becomes an open door that lets an attacker's page make requests as the logged-in victim and read what comes back.
The lesson: Access-Control-Allow-Credentials: true must only ever pair with a specific, trusted origin — never with a reflected or wildcard one.
How BankAPI answers cross-origin requests
When any page calls BankAPI's /me endpoint, the server copies that page's Origin header into the allow-origin response header and permits credentials. The victim's browser therefore attaches their session cookie and then hands the response to the calling site, even if that site is the attacker's.
The attack approach
- Confirm BankAPI reflects the Origin header and returns Allow-Credentials: true.
- From the attacker page in the lab, make a credentialed request to /me.
- Because credentials are allowed for your origin, the victim's cookie rides along and the response is readable.
- Read the auth token out of the response and submit it.
Full walkthrough (spoiler)
If the request runs but you cannot read the body, re-check that credentials are included.
Show the step-by-step solution
- From the attacker page, send a fetch to BankAPI's /me endpoint with credentials included.
- The server reflects your origin and allows credentials, so the browser lets your script read the JSON response.
- Pull the user's auth token from that response.
- Submit the token to the lab, which detects the exfiltration and marks you solved.
Why it works
CORS is enforced by the browser based on what the server says. By reflecting the request's own origin into the allow header and setting allow-credentials, BankAPI tells the browser that the attacker's site is trusted to make authenticated calls and read the result. The same-origin policy is effectively switched off for every origin at once.
Where this happens in the real world
Origin-reflection with credentials is one of the most common CORS findings in bug-bounty programmes, because developers reach for 'reflect the origin' as a quick way to make cross-origin calls work. It maps to Security Misconfiguration (A05) in the OWASP Top 10 (2021), and when the endpoint returns tokens or personal data it leads directly to account takeover.
How to defend against it
- Keep a strict allowlist of trusted origins and only echo Allow-Origin when the request's origin is on it.
- Never combine a reflected or wildcard origin with Allow-Credentials: true.
- Do not trust the Origin header for anything else — it tells you who is asking, not that they are authorised.
- Prefer same-site cookies and short-lived tokens so a leaked response is less damaging.
Try it, then go further
Reading about it is the easy part. Open the lab, try your own approach before peeking at the spoiler, and see how many attempts it takes.
