in

BOLA ve IDOR Nedir? API’lerde Kayıt Bazlı Yetkilendirme

Bir uygulamaya giriş yapabilmek, uygulamadaki her kaydı görme hakkı vermez. Kullanıcının kim olduğunu doğruladıktan sonra, erişmek istediği kayıt üzerinde hangi işlemleri yapabileceğini de denetlemek gerekir. API geliştirmede bu ikinci kontrol unutulduğunda, sağlam görünen bir giriş sistemi bile müşteri bilgilerinin başka hesaplara açılmasını engelleyemez.

Bu yazıda BOLA ve IDOR kavramlarını açıklayacak, örnek bir proje yönetim uygulamasında kayıt erişimini nasıl sınırlandırabileceğimizi inceleyeceğiz. Örnekler tasarım mantığını anlatır; belirli bir canlı sistem üzerinde güvenlik testi veya doğrulanmış uygulama kodu sunmaz.

BOLA ve IDOR ne anlama gelir?

BOLA, “Broken Object Level Authorization” ifadesinin kısaltmasıdır. Türkçede nesne düzeyinde yetkilendirme eksikliği olarak açıklanabilir. API, belirli bir kayda erişen kişinin o kayıt üzerinde istenen işlemi yapmaya yetkili olup olmadığını doğru kontrol etmez. Kullanıcı normalde ilgili uç noktayı kullanabilir; sorun, hangi kayıtlarda bu yetkinin geçerli olduğudur.

OWASP API Security Top 10’un 2023 sürümü, BOLA’yı API1 başlığı altında ele alır. İsteklerde taşınan kayıt kimlikleri sayı, metin veya UUID olabilir. Kontrol eksikliği, yetkisiz okumaya ek olarak değiştirme ve silme işlemlerini de etkileyebilir.

IDOR ise “Insecure Direct Object Reference” anlamına gelir. Uygulamanın doğrudan kayıt referanslarını yeterli erişim kontrolü olmadan kullanmasıyla ilgilidir. İki kavram birçok gerçek senaryoda kesişir; BOLA, API’nin nesne üzerindeki yetki kararına odaklanırken IDOR, doğrudan referans kullanımındaki kontrol eksikliğini tarif eder.

Giriş kontrolü neden yeterli değildir?

Hayalî uygulamamızda Deniz ve Ece farklı müşterilerin projelerinde çalışıyor olsun. İkisinin de geçerli hesabı var. Deniz kendi projesinin görevlerini açabiliyor; Ece de başka bir projenin görevlerini yönetebiliyor. Sunucunun yalnızca “oturum açık mı?” sorusuna bakması, bu iki çalışma alanını birbirinden ayırmaya yetmez.

Örnek bir istek şu biçimde olabilir:

GET /api/gorevler/842

Bu istekteki sayı yalnızca bir kayıt adresidir. Sunucu, adresi bulduktan sonra kaydın hangi projeye bağlı olduğunu ve oturumdaki kişinin o projedeki yetkisini değerlendirmelidir. Tarayıcıda ilgili bağlantının gösterilmiyor olması, API’nin aynı isteği kabul etmeyeceği anlamına gelmez.

Örnek politika şöyle yazılabilir: “Bir çalışan, etkin üyesi olduğu projelerde kendisine görünür olan görevleri okuyabilir; görev kapatma işlemi için ayrıca proje yöneticisi rolü gerekir.” Bu cümle, tek bir kullanıcı rolü kontrolünden daha açıklayıcıdır. Hem kayıtla ilişkiyi hem de yapılacak işlemi tarif eder.

UUID kullanmak sorunu çözer mi?

OWASP’ın IDOR önleme rehberi, karmaşık kimlikleri ek savunma olarak değerlendirir; bunlar erişim kontrolünün yerine geçmez. Tahmin edilmesi zor bir kimlik, paylaşılan bağlantılarda veya başka bir yanıt içinde yine görülebilir. Kimliği öğrenen kişinin kayda erişmeye otomatik olarak hak kazanması doğru değildir.

Proje örneğimizde görev kimliklerini UUID’ye dönüştürdüğümüzü düşünelim. Deniz yanlışlıkla Ece’nin görev bağlantısını aldığında sunucu hâlâ izin kararı vermek zorundadır. Kimlik formatını değiştirmek, proje üyeliği kuralını uygulamaz. Bu yüzden önce erişim kuralını kurmak, sonra kimlik tasarımını ek bir önlem olarak değerlendirmek daha tutarlı bir sıradır.

Yetki kararını nerede vermeliyiz?

OWASP yetkilendirme rehberi, varsayılan olarak erişimi reddetmeyi, gerekli en düşük ayrıcalıkları vermeyi ve izinleri her istekte doğrulamayı önerir. Güvenlik açısından belirleyici karar, istemcinin değiştiremeyeceği sunucu tarafında uygulanmalıdır.

Örnek uygulamamız için aşağıdaki akış bir tasarım önerisidir:

  1. Oturumu doğrula ve sunucunun güvendiği kullanıcı kimliğini edin.
  2. İstenen görevi, kullanıcının erişebileceği proje kapsamı içinde ara.
  3. İşleme özgü politikayı değerlendir: okuma, düzenleme ve silme ayrı kararlardır.
  4. İzin varsa yalnızca gerekli alanları döndür veya izin verilen değişikliği uygula.
  5. İzin yoksa işlemi durdur; yanıtla gereksiz kayıt ayrıntısı açıklama.

Birden fazla işletmeye hizmet veren üründe, istemcinin gönderdiği işletme kimliğini tek başına güvenilir kabul etmeyin. Kullanıcı farklı işletmeler arasında geçiş yapabiliyorsa seçilen işletmenin üyeliği sunucuda doğrulanmalıdır. Aktif üyelik bulunmadan sorgu kapsamı kurulması, görünürde filtreli bir sorgunun yanlış veriye açılmasına neden olabilir.

Veritabanı ek koruma sağlayabilir mi?

PostgreSQL Row-Level Security, satır erişimini politikalarla sınırlandırabilir. Özellik etkinleştirildiğinde uygun politika bulunmaması, normal erişim için varsayılan ret davranışı oluşturur. Bununla birlikte tablo sahipleri genellikle, süper kullanıcılar ve BYPASSRLS yetkili roller ise ilgili kuralları aşabilir. Bu nedenle bağlantı rolü seçimi önemlidir.

Proje uygulamamızda RLS kullanmak, uygulama politikalarına ek bir savunma katmanı olabilir. Ancak veritabanına doğru kullanıcı veya işletme bağlamının nasıl taşındığı ayrıca tasarlanmalıdır. Bağlantı havuzunda önceki isteğin bağlamının kalması gibi uygulama hataları düşünülmeden yalnızca “RLS açık” demek yeterli güvence sağlamaz.

Listeleme ve dışa aktarmayı unutmayın

Tek görev ekranını koruduktan sonra proje listesini, arama sonuçlarını ve CSV dışa aktarma özelliğini de aynı politika açısından inceleyin. Örneğimizde Deniz tekil görev ayrıntısını açamıyor ama tüm görevleri içeren raporu indirebiliyorsa iş kuralı yine bozulmuş olur.

Aynı değerlendirme arka plan işleri için de geçerlidir. Kullanıcı rapor istediğinde işi hangi kapsamla kuyruğa alacağınızı ve tamamlanan dosyayı kimin indirebileceğini belirleyin. Proje üyeliği rapor hazırlanırken kaldırılırsa indirme aşamasında hangi davranışın beklendiğini de ürün kararı olarak yazın. Böylece güvenlik kuralı ekran tasarımından bağımsız hâle gelir.

Küçük bir test matrisi hazırlayın

Geliştirme ortamında iki kullanıcı, iki proje ve sınırlı yetkili bir rol oluşturun. Her kullanıcı için kendi kaydını okuma, diğer projedeki kaydı okuma, yetkisiz düzenleme ve yetkili düzenleme senaryolarını ayrı değerlendirin. Liste ve rapor sonuçlarının da aynı sınırları koruduğunu doğrulayın.

Örnek uygulamamızın kabul ölçütü yalnızca hata kodu olmamalıdır. Reddedilen istekte verinin değişmediğini, yanıtın hassas alan taşımadığını ve toplu işlemin kurallarının açık olduğunu kontrol edin. Yetki kaldırıldıktan sonra eski oturumun ne yapabildiğini de test edin. Bunlar bu yazıda çalıştırılmış testler değil, kendi uygulamanıza uyarlayabileceğiniz senaryolardır.

Bir sonraki API incelemenizde her kayıt için üç soruyla başlayın: Kim erişiyor, hangi kayda erişiyor ve hangi işlemi istiyor? Cevapları açık politikalara dönüştürmek, yalnızca giriş ekranını korumaktan çok daha kapsamlı bir veri erişimi tasarımı sağlar.

Yararlı Oldu Mu?

Bir yanıt yazın

İdempotency Nedir? API’lerde Tekrarlanan İstekleri Yönetmek

Reverse Proxy Nedir? Nginx ile Uygulama Trafiğini Yönetmek