CORS Misconfiguration

Turning off the browser's safety features out of frustration.

The idea

The Same-Origin Policy (SOP) is a critical browser security mechanism that prevents a malicious website (like `hacker.com`) from reading data from another website (like `bank.com`) using JavaScript. Cross-Origin Resource Sharing (CORS) is a feature that allows a server to explicitly relax this policy and allow specific domains to read its data.

A CORS misconfiguration happens when a developer gets frustrated by CORS errors during development and simply allows all domains to read the API data, effectively destroying the SOP protection.

Step 1: Proper CORS. The bank only allows requests from 'bank.com'.

How it works (Strict Origins)

Never configure a production API to reflect the `Origin` header blindly, and never use `*` alongside `Access-Control-Allow-Credentials: true` (most browsers block this anyway, but relying on browser quirks is bad practice). You must specify an explicit whitelist of allowed domains.

# VULNERABLE: The "I just want it to work" configuration
# Reflects ANY domain back to the user, allowing hacker.com to read data.
Access-Control-Allow-Origin: *
# Or even worse (Dynamic Reflection):
Origin = request.headers.get("Origin")
Access-Control-Allow-Origin: {Origin}

# SECURE: Strict Whitelisting
ALLOWED_ORIGINS = ["https://bank.com", "https://api.bank.com"]

Origin = request.headers.get("Origin")
if Origin in ALLOWED_ORIGINS:
    Access-Control-Allow-Origin: {Origin}
    Access-Control-Allow-Credentials: true

Watch out for

Worked example

A crypto exchange API at `api.crypto.com` is configured with `Access-Control-Allow-Origin: *`. A user logs into the exchange, then browses a seemingly innocent cryptocurrency forum (`crypto-chat.com`). The forum contains hidden JavaScript that executes `fetch('https://api.crypto.com/wallet/private-key')`. Because the exchange returns the wildcard `*` CORS header, the victim's browser allows the forum's JavaScript to read the response. The attacker steals the private key and drains the wallet.

Check yourself

Why does a CORS wildcard (`*`) not automatically protect against CSRF attacks?

Correct! SOP/CORS restricts reading. The browser still happily *sends* the CSRF request (with cookies) and executes the state change. It just prevents the attacker from reading the result unless CORS allows it.
Incorrect. Browsers apply CORS (specifically preflight OPTIONS requests) to POST requests if they contain custom headers or JSON.