IDOR Nedir? Başkasının Verisine Erişim Açığı
IDOR (Insecure Direct Object Reference), uygulamanın kullanıcıdan gelen bir kimlikle kayda eriştiği ama kaydın o kullanıcıya ait olup olmadığını denetlemediği erişim denetimi açığıdır. Sonuçta biri başkasının faturasını, mesajını ya da dosyasını görebilir. API dünyasında BOLA adıyla bilinir; kalıcı çözüm sunucu tarafında nesne düzeyinde yetki kontrolüdür.
Fatura indirme adresinin sonunda bir numara var. Kullanıcı bu numarayı değiştirince başka birinin faturası açılıyorsa uygulama ciddi bir hata yapıyor demektir. Kod temiz görünür, testler geçer, tarayıcılar sessiz kalır. Bu yazıda açığın nasıl doğduğunu, gerçek vakaları ve sunucu tarafında nasıl kapatıldığını anlatıyoruz.
IDOR nedir?
IDOR (Insecure Direct Object Reference, güvensiz doğrudan nesne başvurusu), bir erişim denetimi açığıdır. Uygulama kullanıcıdan gelen bir kimlikle kayda erişir, ama kaydın o kullanıcıya ait olup olmadığını denetlemez. Kayıt bir fatura, sipariş, mesaj, dosya ya da kullanıcı profili olabilir. Kimlik ise URL'de, JSON gövdesinde, çerezde ya da gizli bir form alanında taşınır.
Terim, OWASP'ın 2007 Top 10 listesiyle yaygınlaştı. MITRE'deki karşılığı CWE-639'dur: kullanıcının kontrol ettiği anahtarla yetki atlatma. MITRE'nin 2025 CWE Top 25 listesinde CWE-639 altı basamak yükselip 24. sıraya girdi.
IDOR nasıl oluşur?
IDOR, geliştirici kimlik doğrulamayı yetkilendirmeyle karıştırdığında oluşur. Kullanıcı giriş yapmıştır ve uygulama her isteği "giriş yapan biri" diye kabul eder. Ama "bu kişi bu kaydı görebilir mi?" sorusu hiç sorulmaz.
# Zafiyetli desen: kayıt kime ait olursa olsun döner
@app.get("/api/faturalar/<int:fatura_id>")
@giris_gerekli
def fatura_getir(fatura_id):
fatura = Fatura.query.get_or_404(fatura_id)
return fatura.to_dict()
Kodda giriş kontrolü var, sorgu ORM ile kuruluyor, girdi tam sayıya çevriliyor. Klasik bir tarayıcının gözüyle her şey temiz. Eksik olan tek şey sahiplik kontrolüdür. Kimlik sayısal ve sıralıysa sorun büyür, ama sıralı olmasa da açık aynıdır.
IDOR yalnız okumayla sınırlı değildir. Aynı eksik kontrol güncelleme, silme ve dışa aktarma uç noktalarında da çıkar. Bir mobil uygulamanın API'si, bir dosya indirme adresi ya da bir GraphQL sorgusu aynı hatayı taşıyabilir.
Yatay ve dikey yetki aşımı arasındaki fark nedir?
Yatay yetki aşımı, aynı roldeki başka bir kullanıcının verisine erişmektir. Dikey yetki aşımı ise rolünün üstündeki bir işlevi kullanmaktır. IDOR çoğunlukla yatay aşıma yol açar, ama dikey aşımın da kapısını aralayabilir.
| Özellik | Yatay yetki aşımı | Dikey yetki aşımı |
|---|---|---|
| Ne olur? | Bir müşteri başka bir müşterinin kaydını görür. | Sıradan kullanıcı yönetici işlevini çalıştırır. |
| Hangi denetim eksik? | Nesne düzeyi: bu kayıt bu kişinin mi? | İşlev düzeyi: bu rol bu işlemi yapabilir mi? |
| OWASP API karşılığı | API1:2023 BOLA. | API5:2023 BFLA. |
| Tipik örnek | Sipariş numarasıyla başkasının siparişi. | Kullanıcı hesabıyla yönetici uç noktasına istek. |
PortSwigger, yataydan dikeye geçişi de ayrıca anlatır. Yatay bir açık bir yöneticinin hesabına dokunuyorsa, örneğin onun e-posta adresini değiştirebiliyorsa, sonuç yönetici yetkisine uzanır. Bu yüzden "yalnız başka bir müşterinin verisi" diye küçümsenen bir IDOR, zincirin ilk halkası olabilir. Dikey tarafın ayrıntısı için yetki yükseltme yazımıza bak.
IDOR, BOLA ve Broken Access Control aynı şey mi?
Üçü aynı ailenin farklı ölçekteki adlarıdır. Broken Access Control şemsiye kategoridir. IDOR ve BOLA, bu şemsiyenin altındaki nesne düzeyi hatayı anlatır. BOLA, API dünyasında IDOR için kullanılan addır.
- OWASP Top 10 2025, A01 Broken Access Control: listenin birinci sırası. OWASP'a göre test edilen uygulamaların tamamında bir tür erişim denetimi hatası bulundu. Kategoriye 40 CWE ve 32.654 CVE kaydı bağlı.
- OWASP API Security Top 10 2023, API1 BOLA: API'lerin birinci riski. OWASP, kimliğin sıralı sayı, UUID ya da düz metin olabileceğini vurgular.
- CWE-639: IDOR'un MITRE'deki karşılığı. MITRE, IDOR teriminin yol geçişini de kapsadığı için biraz daha geniş olduğunu not eder.
- HackerOne sınıflandırması: IDOR (CWE-639), genel erişim denetimi hatası (CWE-284) ve hatalı yetkilendirme (CWE-285) ayrı başlıklardır.
Rapor yazarken API bulgusunda BOLA, web uygulaması bulgusunda IDOR demek yaygındır. Kategoriyi yılıyla yazmak da iyi bir alışkanlıktır: A01:2025 gibi. Listenin tamamı için OWASP Top 10 2025 yazımıza göz at.
Gerçek IDOR vakaları nelerdir?
En büyük IDOR vakalarından biri, 2019'da ABD'li tapu sigortası şirketi First American Financial'da ortaya çıktı. İkinci bir örnek ise ABD Posta Servisi'nin (USPS) bir API'siydi.
| Vaka | Yıl | Eksik olan kontrol | Sonuç |
|---|---|---|---|
| First American Financial | 2019 | Belge adreslerinde sıralı numara, kimlik doğrulama yok. | 2003'e uzanan yaklaşık 885 milyon belge açıkta kaldı. |
| USPS Informed Visibility API | 2018 | Giriş yapan her kullanıcı başkasının hesap bilgisini sorgulayabiliyordu. | Yaklaşık 60 milyon kullanıcının verisi etkilendi. |
First American olayını 24 Mayıs 2019'da KrebsOnSecurity duyurdu. Şirketin belge paylaşım uygulaması dokuz haneli sıralı belge numaraları kullanıyordu. Belgelerde banka hesap dökümleri, sosyal güvenlik numaraları, vergi kayıtları ve ehliyet görüntüleri vardı. ABD Menkul Kıymetler Komisyonu (SEC), Haziran 2021'de şirkete 487.616 dolar ceza verdi. SEC'e göre bilgi güvenliği ekibi açığı aylar önce tespit etmiş, ama şirket politikasına göre düzeltmemişti.
USPS vakasını yine KrebsOnSecurity, 21 Kasım 2018'de yazdı. Informed Visibility API'sinde nesne düzeyi kontrol yoktu. USPS'in sitesine giriş yapan her kullanıcı başkalarının e-posta, adres ve telefon bilgisini görebiliyordu. Bir araştırmacı sorunu bir yıldan uzun süre önce bildirmişti. Açık, Krebs'in sorusundan sonra kapatıldı.
İki vakanın ortak dersi aynı. Açık teknik olarak basitti ve kurum açığı biliyordu. Eksik olan kod değil, sahiplik kuralını zorunlu kılan süreçti.
Otomatik tarayıcılar IDOR'u neden zor bulur?
Otomatik tarayıcılar IDOR'u zor bulur, çünkü "bu kayıt kime ait?" sorusunun cevabı iş kuralındadır, HTTP yanıtında değil. Tarayıcı 200 yanıtını görür, ama bunun meşru mu yoksa sızıntı mı olduğunu bilemez. SQL injection ya da XSS'te yanıt bir hata ya da yansıma gösterir. IDOR'da yanıt tamamen normal görünür.
Veriler de bu farkı gösteriyor. HackerOne'ın 2025 tarihli 9. Hacker-Powered Security Report'una göre otomatik ajanların (hackbot) geçerli bulgularının yüzde 78'i XSS. Aynı raporda geçerli IDOR bildirimleri bir önceki yıla göre yüzde 29, beş yılda yüzde 116 arttı. HackerOne bu eğilimi, sistemin nasıl işlediğini anlamayı gerektiren açıkların yükselişi olarak yorumluyor.
IDOR testi için en az iki hesap gerekir. Test eden kişi aynı isteği iki farklı oturumla gönderir ve yanıtları karşılaştırır. Burp Suite'in Autorize gibi eklentileri bu karşılaştırmayı hızlandırır. Ama hangi farkın açık olduğuna yine insan karar verir. Aracın temelleri için Burp Suite rehberimize bakabilirsin.
IDOR nasıl önlenir?
IDOR'u önlemenin kalıcı yolu, her istekte sunucu tarafında nesne düzeyinde yetki kontrolü yapmaktır. Kontrol istemcide, gizli bir alanda ya da arayüzde düğmeyi gizleyerek yapılmaz. OWASP Top 10 2025'in A01 bölümü de varsayılan olarak reddetmeyi ve kayıt sahipliğini zorunlu kılmayı önerir.
Sahiplik kontrolü kodda nasıl görünür?
En sağlam desen, sorguyu baştan oturumdaki kullanıcıyla sınırlamaktır. OWASP IDOR Prevention Cheat Sheet bunu bir Rails örneğiyle anlatır. Tüm projeler yerine kullanıcının kendi projeleri içinde arama yapılır.
# Güvenli desen: sorgu oturumdaki kullanıcıyla sınırlı
@app.get("/api/faturalar/<int:fatura_id>")
@giris_gerekli
def fatura_getir(fatura_id):
fatura = Fatura.query.filter_by(id=fatura_id, sahip_id=current_user.id).first()
if fatura is None:
abort(404)
return fatura.to_dict()
Kayıt yoksa da başkasınaysa da aynı 404 yanıtı döner. Böylece uygulama, başkasına ait bir kaydın var olduğunu da sızdırmaz.
Roller işin içine girince kural büyür. Muhasebe çalışanı şirketin tüm faturalarını görebilir, müşteri yalnız kendininkini. Bu kuralları uç noktalara dağıtma, tek bir politika fonksiyonunda topla:
def fatura_okuyabilir(kullanici, fatura):
if kullanici.rol == "yonetici":
return True
if kullanici.rol == "muhasebe":
return fatura.sirket_id == kullanici.sirket_id
return fatura.sahip_id == kullanici.id
PortSwigger de aynı ilkeyi önerir. Uygulama genelinde tek bir denetim mekanizması kullan ve her kaynak için izinli erişimi açıkça tanımla.
Tahmin edilemez kimlik kullanmak yeterli mi?
Yeterli değil. UUID gibi rastgele kimlikler tahmini zorlaştırır, ama erişim denetiminin yerini tutmaz. OWASP, karmaşık kimlikleri yalnız derinlemesine savunma katmanı olarak önerir.
Rastgele kimlik birçok yoldan sızar: paylaşılan bir bağlantı, bir e-posta bildirimi, başka bir API yanıtı ya da bir log dosyası. Kimlik bir kez sızınca kontrolsüz uç nokta yine açıktır. Bugcrowd'un Temmuz 2026 tarihli VRT sınıflandırması da bu farkı yansıtır. Sıralı kimlikle hassas veriyi okuma ya da değiştirme P1, UUID gibi karmaşık kimlikle aynı durum P4 sayılır. Düşük öncelik, açığın kapandığı anlamına gelmez.
Bir tuzak daha var. OWASP API Security, oturumdaki kullanıcı kimliğini URL'deki kimlikle karşılaştırmanın tek başına yetmediğini yazar. Nesne her zaman kullanıcının kimliğini taşımaz. Siparişin sahibi, belgenin paylaşıldığı kişiler, ekibin üyeleri ayrı ayrı denetlenmelidir.
Test edilebilir yetki matrisi nasıl kurulur?
Yetki matrisi, her rolün her kaynak üzerinde hangi işlemi yapabileceğini gösteren tablodur. Matris yazılı olunca otomatik teste dönüşür. Böylece IDOR her sürümde yeniden denetlenir.
| Kaynak ve işlem | Müşteri, kendi kaydı | Müşteri, başkasının kaydı | Muhasebe | Yönetici |
|---|---|---|---|---|
| Fatura okuma | İzinli. | Yasak, 404. | Yalnız kendi şirketi. | İzinli. |
| Fatura indirme | İzinli. | Yasak, 404. | Yalnız kendi şirketi. | İzinli. |
| Adres güncelleme | İzinli. | Yasak, 404. | Yasak, 403. | İzinli. |
| Fatura silme | Yasak, 403. | Yasak, 404. | Yasak, 403. | İzinli. |
Matristeki her yasak hücre bir test olur:
def test_musteri_baskasinin_faturasini_okuyamaz(istemci, ayse, mehmet):
fatura = fatura_olustur(sahip=ayse)
yanit = istemci.oturum_ac(mehmet).get(f"/api/faturalar/{fatura.id}")
assert yanit.status_code == 404
Kurulum için şu sırayı izle:
- Uygulamadaki tüm nesne türlerini çıkar: fatura, sipariş, dosya, mesaj, adres.
- Her nesne için okuma, oluşturma, güncelleme, silme ve dışa aktarma işlemlerini yaz.
- Her rol için izinli ve yasak hücreleri doldur, boş hücre bırakma.
- Her yasak hücre için iki farklı kullanıcıyla çalışan bir test yaz.
- Testleri CI hattına bağla; matriste satırı olmayan yeni uç nokta birleşmesin.
- Erişim reddi yanıtlarını logla, tek oturumdan gelen çok sayıda 403 ve 404 için alarm kur.
IDOR bulunursa ne yapılmalı?
Kendi sisteminde IDOR bulursan önce açığı kapat, sonra logları geriye doğru incele. Açığın daha önce kullanılıp kullanılmadığını anlaman gerekir. Kişisel veri sızmışsa KVKK bildirim yükümlülüğü başlar. Süreç için KVKK veri ihlali bildirimi yazımıza bak.
Başka bir kurumun sisteminde rastlarsan kanıt için gereken en az veriye bak. Veriyi indirme ve kimseyle paylaşma. Kurumun güvenlik bildirim kanalını ya da bug bounty programını kullan. Kanal yoksa USOM'un duyurusuna göre ihbar ve CVE başvuruları artık siberguvenlik.gov.tr üzerinden yürüyor. İzinsiz ya da kapsam dışı test, TCK'nın bilişim suçları bölümüne (md. 243-245) girer.
IDOR'u nerede güvenle öğrenirsin?
IDOR'u öğrenmenin en iyi yolu, iki hesaplı izinli bir ortamda hem açığı hem düzeltmeyi görmektir. AltaySec Akademi'deki Web Uygulama Güvenliği yolu bunu adım adım işler. Nesne düzeyi yetki dersi IDOR ve BOLA'yı birlikte anlatır. Fonksiyon düzeyi yetki dersi dikey tarafı ve sunucu tarafı düzeltmeyi gösterir.
Ardından Sahiplik Sınırını Bulmak labında izinli bir hedefte pratik yaparsın. API tarafı için API yetkilendirme dersine geç. Bug bounty'ye hazırlanıyorsan IDOR'un listedeki yerini en sık bulunan 10 açık yazımızda gör.
Kaynaklar
- OWASP Top 10:2025, A01 Broken Access Control.
- OWASP API Security Top 10 2023, API1 BOLA.
- OWASP IDOR Prevention Cheat Sheet.
- MITRE CWE-639.
- PortSwigger Web Security Academy: Access control.
- KrebsOnSecurity: First American Financial (2019).
- SEC: First American cezası (2021).
- HackerOne 2025 Hacker-Powered Security Report.
Sık sorulan sorular
IDOR ile BOLA arasında fark var mı?
Özünde aynı açığı anlatırlar. IDOR, OWASP'ın web uygulamaları için 2007'de yaygınlaştırdığı terimdir. BOLA ise OWASP API Security Top 10'da API'ler için kullanılan addır ve 2023 listesinin birinci sırasındadır. MITRE ikisini de CWE-639 ile ilişkilendirir. API raporunda BOLA, web uygulaması raporunda IDOR demek yaygındır.
UUID kullanmak IDOR'u önler mi?
Önlemez, yalnız zorlaştırır. Rastgele kimlik paylaşılan bağlantılardan, e-postalardan, loglardan ya da başka API yanıtlarından sızabilir. Sızdığı anda sahiplik kontrolü olmayan uç nokta yine açıktır. OWASP, karmaşık kimlikleri derinlemesine savunma katmanı olarak önerir. Asıl savunma, her istekte sunucu tarafında yapılan nesne düzeyi yetki kontrolüdür.
IDOR bug bounty'de ne kadar önemli sayılır?
Etkisine göre değişir. Bugcrowd'un 2026 sürümü VRT sınıflandırmasında sıralı kimlikle hassas veriyi okuma ya da değiştirme en yüksek öncelik olan P1'dir. Aynı durum UUID gibi karmaşık kimlikle P4'e iner, hassas olmayan veri ise P5 sayılır. HackerOne'ın 8. raporunda IDOR, bug bounty'de en sık bildirilen dördüncü açıktır.
IDOR'u otomatik tarayıcıyla bulabilir miyim?
Çoğunlukla bulamazsın. Tarayıcı, bir yanıtın meşru mu yoksa başkasına ait veri mi olduğunu bilemez, çünkü sahiplik kuralı iş mantığındadır. Burp Suite'in Autorize gibi eklentileri iki oturumu karşılaştırarak işi hızlandırır. Ama hangi farkın açık olduğuna yine sen karar verirsin. En güvenilir yöntem, yetki matrisine dayalı otomatik testlerdir.
IDOR yalnız sayısal kimliklerde mi olur?
Hayır. Kimlik bir kullanıcı adı, e-posta adresi, dosya adı, sipariş kodu ya da UUID olabilir. Açığın kökü kimliğin biçimi değil, sunucunun sahiplik denetimini atlamasıdır. Sıralı sayılar açığı keşfetmeyi kolaylaştırır. Ama rastgele görünen her kimlik de doğru kontrol yoksa aynı riski taşır. OWASP API Security de bunu vurgular.
- idor nedir
- insecure direct object reference
- bola nedir
- erişim denetimi
- web güvenliği