CORS Misconfiguration Lab: Steal a Token From Another Site

✨ AI Summary
BankAPI echoes whatever 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.
Lab at a glance: Intermediate · 90 XP · about 15 minutes · runs in your browser, no signup or setup. Try it yourself first; the full solution is behind a spoiler below.

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
  1. From the attacker page, send a fetch to BankAPI's /me endpoint with credentials included.
  2. The server reflects your origin and allows credentials, so the browser lets your script read the JSON response.
  3. Pull the user's auth token from that response.
  4. 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.

Core principleAllow-Credentials: true may only accompany a single trusted origin from a strict allowlist — never a reflected origin and never a wildcard.

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.
Mr Elite tip: Test by sending requests with an Origin header set to a random domain. If the server reflects it into Access-Control-Allow-Origin alongside Allow-Credentials: true, you have found the bug.

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.

❓ Frequently asked questions

What is a CORS misconfiguration?
When a server's cross-origin headers are too permissive — for example reflecting any origin and allowing credentials — so untrusted sites can make authenticated requests and read the responses.
Why is reflecting the Origin dangerous?
Reflecting the caller's origin plus Allow-Credentials: true tells the browser every site is trusted, so an attacker page can act as the logged-in victim and read private data.
Isn't CORS supposed to protect me?
CORS relaxes the same-origin policy in a controlled way. Misconfigured, it relaxes it for everyone. Correct CORS uses a strict allowlist of trusted origins.
How do I configure CORS safely?
Maintain an allowlist, echo Allow-Origin only for origins on it, and never pair a reflected or wildcard origin with Allow-Credentials: true.
⚡
Join free to earn XP for reading this article Track your progress, build streaks and compete on the leaderboard.
Join Free
Lokesh N. Singh aka Mr Elite
Lokesh N. Singh aka Mr Elite
Founder, Securityelites · AI Red Team Educator
Founder of Securityelites and creator of the SE-ARTCP credential. Working penetration tester focused on AI red team, prompt injection research, and LLM security education.
About Lokesh ->

Leave a Comment

Your email address will not be published. Required fields are marked *