Merhaba, "Yetkilendirme ve Erişim Kontrolü Mantık Hataları" modülümüze devam ediyoruz. Önceki dersimizde, bir isteğin geçtiği farklı katmanların aynı URL'i farklı yorumlaması sonucu ortaya çıkan normalizasyon tutarsızlıklarının, yetkilendirme kontrollerini nasıl atlatabileceğini derinlemesine inceledik. Bu, bir kullanıcının erişmeye çalıştığı kaynağın kimliğini manipüle etmeye odaklanan bir zafiyet sınıfıydı.
Bu dersimizde ise odağımızı kaynağın kendisinden, isteği yapan kullanıcının kimliğine ve yetkilerine çeviriyoruz. Yetkilendirmenin temel taşlarından biri olan Rol Tabanlı Erişim Kontrolü (RBAC) mekanizmalarındaki mantık hatalarını ve bu hataların yetki yükseltme (privilege escalation) için nasıl istismar edilebileceğini kod seviyesinde analiz edeceğiz. Hedefimiz, rol hiyerarşilerindeki tasarım kusurlarını ve rol atama işlemlerindeki uygulama zafiyetlerini bir uzman gözüyle tespit etmeyi öğrenmek olacak.
Rol Tabanlı Erişim Kontrolünün (RBAC) Temelleri
Kod analizine geçmeden önce, RBAC modelinin temel bileşenlerini ortak bir terminoloji üzerinden hatırlayalım. RBAC, bir kullanıcının ne yapabileceğini, ona atanmış roller aracılığıyla tanımlar. Bu model genellikle üç ana unsurdan oluşur:
- Güvenlik Sorumlusu (Security Principal): Eylem gerçekleştiren varlık. Bu bir kullanıcı, bir kullanıcı grubu veya bir servis hesabı (service principal) olabilir.
- Rol Tanımı (Role Definition): Bir dizi iznin (permission) koleksiyonudur. Örneğin, "Okuma", "Yazma", "Silme" gibi izinleri içeren bir "Katkıda Bulunan" (Contributor) rolü. Bu izinler, kullanıcının hangi eylemleri (
Actions) gerçekleştirebileceğini ve hangilerini gerçekleştiremeyeceğini (NotActions) belirtir. - Kapsam (Scope): Rolün geçerli olduğu kaynak veya kaynaklar kümesidir. Rol ataması, bir güvenlik sorumlusuna belirli bir kapsamda bir rol tanımını bağlama işlemidir. Bu, bir abonelik, bir kaynak grubu veya tek bir kaynak olabilir.
Aşağıdaki diyagram, bu üç bileşenin bir rol atamasında (role assignment) nasıl bir araya geldiğini görselleştirmektedir.

Bu görsel, RBAC'nin üç temel ayağını özetlemektedir: (1) Kimin erişim istediğini belirten Güvenlik Sorumlusu, (2) ne tür eylemlere izin verildiğini tanımlayan Rol Tanımı ve (3) bu izinlerin nerede geçerli olduğunu sınırlayan Kapsam. Bu üç unsurun birleşimi, Rol Atamasını oluşturur.
Kod denetimindeki amacımız, bu modelin implementasyonundaki mantıksal çatlakları bulmaktır. Zafiyetler genellikle bu bileşenlerin kendisinden çok, aralarındaki ilişkilerin ve etkileşimlerin yanlış kurgulanmasından kaynaklanır.
1. Rol Hiyerarşisi Mantık Hataları
Roller nadiren izole bir şekilde bulunur. Genellikle aralarında bir hiyerarşi veya mantıksal bir ilişki vardır. Örneğin, bir Admin rolü, bir Editor rolünün tüm yetkilerine ve daha fazlasına sahip olabilir. Bu hiyerarşilerdeki tasarım hataları, beklenmedik yetki yükseltme yolları yaratabilir.
Kod Denetimi Stratejisi:
-
Rol Tanımlarını ve Miras Zincirini Bulun:
Rollerin ve içerdikleri izinlerin nerede tanımlandığını tespit edin. Bu, veritabanındaki birrolestablosu, birroles.jsongibi konfigürasyon dosyası veya kodun içine gömülmüşenumveyaconstyapılarında olabilir.- Tehlikeli Soru: Bir rol, başka bir rolden izinleri miras alıyor mu? Örneğin,
ModeratorrolüUserrolünden miras alıyorsa,Userrolüne eklenen "kendi hesabını sil" gibi zararsız görünen bir izin,Moderator'ın da bu yetkiye sahip olmasına neden olur mu? Bu durum, moderatörlerin yanlışlıkla kendi hesaplarını silmesine yol açabilir veya daha karmaşık senaryolarda istismar edilebilir.
- Tehlikeli Soru: Bir rol, başka bir rolden izinleri miras alıyor mu? Örneğin,
-
"Meta" İzinleri Avlayın:
En tehlikeli izinler, diğer kaynakları değil, güvenlik modelinin kendisini değiştiren izinlerdir. Kodda özelliklecan_assign_roles,edit_permissions,create_user_with_rolegibi isimlere sahip izinleri arayın.- Tehlikeli Soru: Bir
UserManagerrolü, yeni kullanıcılar oluşturabiliyor mu? Peki bu kullanıcılara hangi rolleri atayabiliyor? EğerUserManager, kendisinden daha yüksek yetkili birBillingAdminrolü atayabiliyorsa, bu dolaylı bir yetki yükseltmedir. Kişi doğrudan fatura bilgilerine erişemez, ama bu erişime sahip bir kullanıcı yaratabilir.
- Tehlikeli Soru: Bir
-
Çakışan Rollerin Davranışını Analiz Edin:
Bir kullanıcıya aynı kaynak üzerinde çakışan iki rol (örneğin, hemEditorhem deReadOnly) atanırsa sistem nasıl davranır?
* **Tehlikeli Soru:** Sistem en kısıtlayıcı (`ReadOnly` - deny by default) politikayı mı, yoksa en izin verici (`Editor` - allow by default) politikayı mı uygular? Güvenli sistemler genellikle en kısıtlayıcı olanı tercih eder. Kodda bu birleştirme (merge) mantığını bulun ve davranışını doğrulayın. Bu mantık genellikle kullanıcının oturum nesnesi oluşturulurken veya bir kaynağa erişim kontrolü yapılırken bulunur.
2. Rol Atama Kodu Mantık Hataları
Rol hiyerarşisi mükemmel tasarlanmış olsa bile, bu rollerin kullanıcılara atanmasını sağlayan kodun kendisi zafiyet içerebilir. Bu genellikle "kullanıcı yönetimi" veya "takım yönetimi" gibi özelliklerde bulunur.
Kod Denetimi Stratejisi:
Saldırı yüzeyi, bir kullanıcının başka bir kullanıcının rolünü değiştirebildiği herhangi bir fonksiyondur. Genellikle POST /api/teams/{id}/members veya PUT /api/users/{id}/role gibi API endpoint'leri aracılığıyla tetiklenir.
-
Giriş Noktasını ve Yetkilendirmesini Bulun:
Rol atama işlemini başlatan controller metodunu veya handler fonksiyonunu tespit edin. Bu metoda erişim hangi yetkiye bağlanmış? Örneğin,[Authorize(Roles = "TeamAdmin")](C#),@permission_classes([IsTeamManager])(Python/Django) gibi bir kontrol var mı? -
Temel Mantık Hatasını Arayın: Atayan, Atanandan Daha mı Güçlü?
Bu zafiyet türünün en klasik ve en tehlikeli örneği, bir yöneticinin kendisinden daha güçlü bir rolü başka bir kullanıcıya (veya kendisine) atayabilmesidir.Aşağıda Python ve Django REST Framework kullanılarak yazılmış tehlikeli bir kod deseni bulunmaktadır:
# TEHLİKELİ DESEN # Sadece takım yöneticileri bu endpoint'e erişebilir. @permission_classes([IsTeamManager]) @api_view(['POST']) def add_user_to_team(request, team_id): # İstek yapan kullanıcının bu takımın yöneticisi olduğu varsayılıyor. user_to_add_id = request.data.get('user_id') role_to_assign = request.data.get('role_name') # Örn: "member", "manager", "org_admin" # ZAFİYET: 'role_to_assign' üzerinde hiçbir kontrol yok. # Bir TeamManager, bu endpoint'i kullanarak başka bir kullanıcıyı # takıma "org_admin" rolüyle ekleyebilir ve yetkisini yükseltebilir. user = User.objects.get(id=user_to_add_id) team = Team.objects.get(id=team_id) # Rol atama fonksiyonu çağrılıyor team.add_member(user, role=role_to_assign) return Response({"status": "success"})
-
Güvenli Deseni Doğrulayın:
Yukarıdaki zafiyeti düzeltmek için kodun, rolü atayan kullanıcının bu işlemi yapma yetkisini ve atamak istediği rolün geçerliliğini doğrulaması gerekir.# GÜVENLİ DESEN @permission_classes([IsTeamManager]) @api_view(['POST']) def add_user_to_team(request, team_id): user_to_add_id = request.data.get('user_id') role_to_assign = request.data.get('role_name') # DÜZELTME 1: Atanabilecek roller beyaz listeye alınır. ALLOWED_ROLES_TO_ASSIGN = ["member", "guest"] if role_to_assign not in ALLOWED_ROLES_TO_ASSIGN: return Response({"error": "You cannot assign this role."}, status=403) # DÜZELTME 2 (Daha Dinamik): İstek yapan kullanıcının, atamak istediği rolden # daha yüksek bir hiyerarşide olup olmadığını kontrol et. requesting_user = request.user if not requesting_user.has_permission_to_assign(role_to_assign): return Response({"error": "Forbidden"}, status=403) # ... geri kalan kod ... return Response({"status": "success"})Kod denetiminde göreviniz, bu tehlikeli deseni bulmak ve
DÜZELTME 1veyaDÜZELTME 2gibi bir güvenlik mekanizmasının var olup olmadığını doğrulamaktır. Özelliklerequest.data.get('role')gibi kullanıcıdan doğrudan alınan ve hiçbir kontrolden geçmeden bir güvenlik fonksiyonuna parametre olarak verilen değerler, en büyük tehlike işaretleridir.
Sonuç
Bu derste, yetkilendirme mantığının en hassas noktalarından biri olan rol yönetimi ve hiyerarşisi üzerine odaklandık. Otomatik araçların genellikle tespit etmekte zorlandığı, derinlemesine mantık analizi gerektiren zafiyetleri nasıl avlayacağımızı gördük.
Temel Çıkarımlar:
- Yetki yükseltme, mantıkta gizlidir: Zafiyetler, genellikle
if (user.isAdmin)gibi bariz kontrollerin eksikliğinden değil, roller arasındaki karmaşık ilişkilerin ve rol atama sürecindeki varsayımların istismar edilmesinden kaynaklanır.
- İki temel alanı denetleyin: Hem rollerin statik tanımını (hiyerarşi, miras, "meta" izinler) hem de rollerin dinamik olarak atandığı kodu (yetkilendirme, girdi doğrulama) analiz edin.
- Kritik soruyu sorun: "Bir kullanıcı, mevcut yetkilerini kullanarak doğrudan veya dolaylı olarak kendisini veya başkasını daha yetkili hale getirebilir mi?" Kod denetiminiz bu sorunun cevabını bulmaya odaklanmalıdır.
Bu dersle birlikte "Yetkilendirme ve Erişim Kontrolü Mantık Hataları" modülümüzü tamamladık. Bir sonraki modülde, çok daha farklı ama bir o kadar da kritik bir konuya geçiş yapacağız: Çok Kiracılı (Multi-tenant) Mimarilerde Veri İzolasyonu. Artık bir kullanıcının "ne yapabildiğinden" çok, özellikle SaaS gibi platformlarda "hangi veriyi görebildiğine" odaklanacağız ve ORM sorgularında veya veri erişim katmanlarındaki hataların, bir kiracının verisinin diğerine sızmasına nasıl neden olabileceğini inceleyeceğiz.