Konuyu Okuyanlar: 1 Ziyaretçi

IDOR ve Broken Access Control: Tespit ve Korunma Rehberi

IDOR ve Broken Access Control: Tespit ve Korunma Rehberi
[center]
[Resim: attachment.php?aid=128]
[/center]

Selam TurkTeam, BlueTornado yazıyor.

Broken Access Control, OWASP Top 10 2021 listesinde A01 olarak birinci sıradaydı. Altındaki en sık pratik bulgulardan biri de IDOR (Insecure Direct Object Reference). Bu konuda IDOR'un ne olduğunu, Broken Access Control ile ilişkisini, labda nasıl güvenli test edileceğini ve sunucu tarafı korunmayı anlatıyorum.

Konuda Anlatılacaklar
  1. Broken Access Control ve IDOR nedir?
  2. Yatay / dikey yetki karışıklığı
  3. Lab ortamı: Juice Shop ve basit demo API
  4. Tespit adımları: parametre manipülasyonu
  5. Korunma: yetki kontrolleri, dolaylı referanslar
  6. İleri seviye: mass assignment, GraphQL, BOLA
  7. Kaynakça ve yasal uyarı

1) Teori: Erişim Kontrolü Bozulunca Ne Olur?
Erişim kontrolü iki soruya cevap verir: "Bu kullanıcı kim?" (kimlik doğrulama) ve "Bu işlem / nesne için yetkisi var mı?" (yetkilendirme). Broken Access Control, ikinci sorunun atlanması veya yanlış cevaplanmasıdır.

IDOR: Uygulamanın iç nesneye (sipariş, dosya, mesaj) kullanıcı kontrollü bir kimlikle (id, uuid, dosya adı) doğrudan referans vermesi ve sahiplik/yetki kontrolü yapmaması.

Kod:
# Tehlikeli kalıp @app.get("/api/orders/{order_id}") def get_order(order_id: int): # Sadece login kontrolü var, sahiplik yok return db.orders.get(order_id)

Kod:
# Doğru yönde @app.get("/api/orders/{order_id}") def get_order(order_id: int, user=Depends(current_user)): order = db.orders.get(order_id) if order is None or order.owner_id != user.id: raise HTTPException(404) # veya 403 return order

IDOR yalnızca sayısal id'lerde olmaz. Tahmin edilebilir dosya yolları, e-posta adresleri, hesap numaraları da nesne referansı olabilir.

Alıntı:UUID kullanmak IDOR'u "çözmez". Keşfi zorlaştırabilir; yetki kontrolü olmadan bilinmeyen UUID hâlâ başkasının verisine açılan kapıdır (ör. sızıntı, referrer, bildirim linki).

2) Yatay ve Dikey Erişim
  • Yatay (horizontal): Aynı roldeki A kullanıcısı, B kullanıcısının kaynağına erişir (klasik IDOR).
  • Dikey (vertical): Normal kullanıcı admin işlevine erişir (
    Kod:
    /admin/deleteUser
    ).
  • Bağlam / işlev: Kullanıcı kendi siparişini görebilir ama "iade onayla" gibi ayrıcalıklı işlemi yapamamalıdır.

Kod:
# Dikey örnek (kavramsal) POST /api/admin/users/42/role {"role":"admin"} # Rol kontrolü yoksa Broken Access Control

3) Lab Ortamı
Kod:
docker pull bkimminich/juice-shop docker run --rm -p 3000:3000 bkimminich/juice-shop

Juice Shop'ta sepet, geri bildirim ve kullanıcı challenge'larında erişim kontrolü zafiyetleri bilinçli olarak vardır. Spoiler vermeden: kendi hesabınızla oluşturduğunuz nesnelerin kimliklerini not alıp, başka hesapla aynı kimliğe istek atmayı deneyin (yalnızca localhost).

Basit bir yerel demo için:

Kod:
# Flask iskeleti (kasıtlı zayıf - sadece lab) orders = {1: {"owner": "ali", "item": "kitap"}, 2: {"owner": "ayse", "item": "kalem"}} @app.get("/orders") def get(id: int): return orders[id] # sahiplik yok!

[center][/center]

4) Kavram Referansı

Direct object reference:
Kod:
GET /invoices/18442.pdf GET /api/v1/messages/9921

Indirect reference map: Kullanıcıya geçici, oturuma bağlı rastgele anahtar vermek. Yine de sunucuda yetki doğrulanmalıdır.

Kod:
# Kavramsal eşleme session_refs["a8f0..."] = {"type":"invoice", "id":18442, "owner": user.id}

Forced browsing: Auth gerektiren URL'lerin tahmin edilerek gezilmesi.

Kod:
/admin/dashboard /api/internal/metrics

CORS yanlış yapılandırması: Access-Control-Allow-Origin: * ve credentials birlikte veya aşırı geniş origin listesi, tarayıcıdan yetkisiz okumayı kolaylaştırabilir.

5) Tespit: Adım Adım (Yasal Lab)

Adım 1 - İki hesap oluşturun. A ve B. A ile kaynak yaratın (sipariş, not, dosya).

Adım 2 - İstekleri kaydedin. Burp / DevTools ile
Kod:
order_id
,
Kod:
userId
,
Kod:
doc
parametrelerini bulun.

Kod:
# Örnek istek GET /api/orders/105 HTTP/1.1 Cookie: session=A_SESSION

Adım 3 - Kimliği değiştirin. 105 yerine B'nin veya A'nın diğer kaydını koyun; oturum A'da kalsın.

Kod:
GET /api/orders/106 HTTP/1.1 Cookie: session=A_SESSION

Adım 4 - Yanıtı yorumlayın.
  • 200 + B'nin verisi -> yatay IDOR güçlü aday
  • 403/404 -> kontrol var (yine de başka uçları deneyin)
  • 301 ile başka yere gitmek -> mantığı anlayın

[center][/center]

Adım 5 - Metotları deneyin. GET güvenli görünürken PUT/DELETE/PATCH açık kalmış olabilir.

Kod:
PUT /api/orders/106 {"status":"refunded"}

Adım 6 - Encoding / tip oyunları.
Kod:
106
,
Kod:
106.0
, dizi
Kod:
[106]
, JSON
Kod:
{"id":106}
gibi alternatif temsiller bazı framework'lerde farklı kod yollarına düşebilir.

6) Korunma
  • Her istekte sunucu tarafı yetki kontrolü (deny by default)
  • "Bu nesne bu kullanıcıya mı ait?" sorusunu merkezi bir policy katmanında sorun
  • Sadece UI'da butonu gizlemek yetmez
  • Admin işlevlerini ayrı rol ve mümkünse ayrı ağ/segment ile koruyun
  • Loglayın: access.denied olayları
  • Otomatik test: A kullanıcısı B kaynağına 403 bekleyen entegrasyon testleri

Kod:
# Pseudo-policy def authorize(user, action, resource): if user.role == "admin" and action in ADMIN_ACTIONS: return True if resource.owner_id == user.id and action in OWNER_ACTIONS: return True return False

Kod:
# Django örneği class OrderDetail(LoginRequiredMixin, UserPassesTestMixin, DetailView): def test_func(self): return self.get_object().owner_id == self.request.user.id

[center][/center]

7) İleri Seviye
BOLA (Broken Object Level Authorization): OWASP API Top 10'da API'ler için IDOR'un karşılığıdır. API güvenliği konusunda ayrıca ele alınacak.

Mass assignment / bağlama: Kullanıcının
Kod:
{"role":"admin"}
alanını body'de gönderip profilini yükseltmesi.

Kod:
# Tehlikeli user.update(request.json) # Güvenli: allowlist user.update({k: request.json[k] for k in ("name", "bio")})

GraphQL: Nesne id'leri ile başka kullanıcı kayıtlarını çekmek; field-level authorization gerekir.

Batch / IDOR otomasyonu: Intruder ile id bruteforce yalnızca yetkili labda; üretimde rate limit ve izleme şarttır.

Kod:
# Rapor dili Bulgu: IDOR / Broken Access Control (CWE-639) Endpoint: GET /api/orders/{id} Kanıt: Kullanıcı A, kullanıcı B siparişini 200 ile okudu Öneri: sahiplik kontrolü + test otomasyonu

8) Sonuç
IDOR, Broken Access Control ailesinin görünür yüzüdür. UUID, "gizli URL" veya sadece frontend kontrolü yetmez. Sunucuda her nesne erişiminde yetki sorun; A/B hesap testlerini CI'ya ekleyin.

Kaynakça
Yasal Uyarı
Erişim kontrolü testleri yalnızca kendi uygulamalarınızda veya yazılı yetki kapsamındaki pentestlerde yapılmalıdır. Başkasının hesabına veya sistemine izinsiz erişim denemesi TCK 243-245 kapsamında suç oluşturabilir. Eğitim amaçlıdır; sorumluluk uygulayana aittir.


Ek DosyalarEkran Görüntüleri
   
Cevapla



Hızlı Menü: