We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Cross-Origin Resource Sharing

CORS (Cross-Origin Resource Sharing) controls which browser-based JavaScript origins are allowed to read responses from your server. It's a browser security feature, not authentication, and it provides no protection against requests from curl, Postman, or other server-side code.

Click to play video

Preflight

For some cross-origin requests, the browser sends a preflight OPTIONS request before the real one. If the response doesn't approve the requesting origin, method, and headers, the browser refuses to send the actual request. Requests that don't require preflight may still be sent, but JavaScript can't read their responses unless the server grants access.

Assignment

Bearly Secure's intern was sick of seeing CORS errors, and built the API to reflect every requesting Origin into Access-Control-Allow-Origin (meaning it takes the origin from the request header and sends it in the response) and also sets Access-Control-Allow-Credentials: true. Instead of limiting access, this tells the browser that any site asking for authenticated data is allowed to read it!

An attacker's page can now make a credentialed request:

const response = await fetch("http://localhost:3000/api/account", {
  credentials: "include",
});
const account = await response.json();

By default, the same-origin policy prevents the attacker from reading cross-origin responses. However, the account API does send CORS headers that grant the attacker's origin access (silly intern), so the browser exposes that response to the attacker's JavaScript.