Intermediate·250 points·0 solves
Aperture Metrics — CORS Misconfiguration
Learn to recognise and fix a CORS misconfiguration: reflecting an arbitrary Origin header back in Access-Control-Allow-Origin, combined with Access-Control-Allow-Credentials: true, tells every browser on the internet that any site may read this response WITH the signed-in user's cookies attached. You will not be asked to build an attack page — the lab shows you the dangerous request and its response. Your job is to patch the handler.
The handler for GET /api/data does `if origin_header: headers["Access-Control-Allow-Origin"] = origin_header; headers["Access-Control-Allow-Credentials"] = "true"` — a direct, unconditional reflection with no allow-list check at all. Browsers enforce the same-origin policy on your behalf, but a server can opt a response OUT of it with these two headers — and this one opts out for literally any caller. Credentials ("true") is what turns a readable-by-anyone bug into a readable-with-your-session bug: without it, an attacker site could still read the response, just not as the victim. The fix has two independent, acceptable forms: validate Origin against an explicit allow-list before reflecting it (and only then allow credentials), OR stop allowing credentials for any origin you have not validated. Wildcard "*" and credentials are also mutually exclusive by browser rule — a wildcard with credentials is simply ignored, which is its own kind of silent failure.
Your tasks
1
Open the lab and read the handler
The vulnerable handle_api_data() function is shown in full on the lab page — no recon step. Find the two lines that set the CORS headers.
2
See the risk, without crafting anything
Click "Run this demo" on the lab page. It issues a GET /api/data with Origin: https://attacker.example for you and shows the raw response headers — notice the Origin was reflected back together with Allow-Credentials: true.
3
Add an allow-list
In the editor, give ALLOWED_ORIGINS the one real origin that should be trusted, and only set Access-Control-Allow-Origin when the incoming Origin matches it exactly.
4
Keep credentials inside the allow-listed branch
Access-Control-Allow-Credentials: true must only ever be set alongside a validated, non-wildcard Origin — never unconditionally.
5
Run the checker
The checker sends a request with a random, unlisted Origin and confirms it is no longer granted a credentialed reflection, then confirms a plain request still works. Passing reveals the flag.
Submit the flag
Start the lab, capture the flag from the running machine, and submit it here.