Cross-origin resource sharing (CORS)
When your browser’s “no strangers allowed” policy gets a little too friendly
~15mins estimatedSelect your ecosystem
What is CORS?
Cross Origin Resource Sharing (CORS) is a browser-based security mechanism that allows a server to explicitly permit a website from a different domain to access its resources. Under the Same Origin Policy (SOP), browers strictly block "cross-origin" requests (e.g., site-a.com trying to read data from api-b.com) to prevent malicious sites form stealing sensitive user data. CORS acts as a permission slip system: when a web app requests a resource from a different origin, the server uses specific HTTP headers to tell the browser whether that request is trusted and should be allowed to proceed.
By default, web browsers are paranoid. If you are logged into your bank at bank.com, a malicious site at evil-cats.com shouldn't be able to use your browser session to fetch your account balance. This is the Same-Origin Policy (SOP) in action.
However, modern web applications are often spread across multiple domains (like an API on a subdomain). To make this work, developers use CORS to punch a hole in the SOP for specific, trusted origins. The vulnerability arises when developers get lazy and punch a hole big enough for everyone to walk through!
About this lesson
In this lesson, you will explore the mechanics of CORS and how a lazy configuration can lead to total data exposure. You'll walk through a fictional exploit scenario, analyze vulnerable Node.js code, and learn how to implement a strict allow-list to ensure your API only talks to those it trusts.
Imagine FinTrack, a popular personal finance app. FinTrack's developers want their web dashboard at dashboard.fintrack.com to fetch data from their API at api.fintrack.com. To make development easier, they set their CORS policy to be wide open.
Enter Malicious Ray. Ray creates a website called free-crypto-giveaway.io and sends a phishing link to Sarah, a loyal FinTrack user. Sarah, currently logged into FinTrack in another tab, clicks the link.
While Sarah looks at a fake "Claim your Bitcoin" buttom, a hidden script on Ray's site sends a background request to api.fintrack.com/me/balance. Because FinTrack's server is configured to trust any origin, Sarah's browser allows Ray's malicious site to read her private financial data. Ray now has her account balance and recent transactions without ever needing her password.
Developers often use this pattern in Python/Flask to reflect the requester's origin back to them:
Why is this dangerous?
By echoing req.headers.origin, you are telling the browser that any site, even Ray's, is an allowed origin. When combined with Allow-Credential: true, the browser includes Sarah's session cookies, giving Ray full access to her account data.
The impacts of CORS misconfiguration
The consequences of a broken CORS policy can be devastating:
- Data exfiltration: Attackers can steal PII (Personally Identifiable Information), private messages or financial records.
- Privacy violations: User sessions can be hijacked to map out internal network structures or private metadata.
- Regulatory fines: Massive data leaks caused by misconfigurations often lead to heavy penalties under GDPR or CCPA.
In production, don't manage headers manually. Use the Flask-CORS library to implement a strict allowlist.
For complex requests (like those using PUT, DELETE, or custom JSON headers), the browser doesn't just send the data. It sends a preflight request using the OPTIONS method first.
The browser asks: "Are you okay with me sending a POST request from fintrack.com?" The server responds with its policy. If the handshake fails, the real request is never even sent.
CORS is only one layer of security. To truly harden your Python app, use Talisman to set a Content Security Policy (CSP).
While CORS prevents other sites from reading your data, CSP prevents malicious scripts from running on your site in the first place.
Test your knowledge!
Keep learning
If you’re ready to dive deeper into browser security, cross-origin communication, and modern API defense, check out these high-quality resources:
MDN Web Docs: Cross-Origin Resource Sharing (CORS): The definitive technical manual for how CORS headers, preflights, and credentials work in the browser.
OWASP information on CORS
Snyk blog: Security implications of cross-origin resource sharing (CORS) in Node.js