

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Still calibrating
click for more info
Not enough gems
Cost: 6 gems
1: Cross-Site Scripting (XSS)
incomplete
2: Fix Cross-Site Scripting
incomplete
3: Cross-Site Request Forgery (CSRF)
incomplete
4: CSRF Tokens
incomplete
5: Content Security Policy
incomplete
6: Legitimate Inline Scripts
incomplete
7: Sandboxing 'iframe' Elements
incomplete
8: Clickjacking
incomplete
9: Same-Origin and Referrer Policies
incomplete
10: Cross-Origin Resource Sharing
incomplete
11: CORS in Express
incomplete
12: Helmet
incomplete
Back
ctrl+,
Next
ctrl+.
This lesson's interactive features are locked, please to keep using them
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
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.
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.