Bölüm 14
Authorization & Access Control (Yetkilendirme ve Erişim Kontrolü)
Bölüm 12 (authN vs authZ), Bölüm 3 (complete mediation, fail secure). İleri referans: Bölüm 15 (IDOR — nesne düzeyi erişim).
Yetkilendirmeyi, kimlik doğrulamadan ayrı ve ondan sonra gelen bir katman olarak kavrayacak; dikey ve yatay yetki yükseltmeyi ayırt edecek; "deny by default" ve "sunucu tarafında, her istekte zorla" ilkelerini ve bunların neden OWASP'ın 1 numaralı riskini (Broken Access Control) çözdüğünü göreceksiniz.
1. Giriş
Erişim kontrolü, OWASP Top 10:2021 listesinin 1 numarasıdır (A01: Broken Access Control) — ve bu bir tesadüf değildir. Yetkilendirme kusurları hem çok yaygın hem de yıkıcıdır: bir kullanıcının erişmemesi gereken bir kaynağa erişmesi, doğrudan veri ihlali, yetki yükseltme ve sistem devri demektir. Dahası, bu kusurlar genellikle "sessizdir": uygulama beklendiği gibi çalışır, sadece yanlış kişilere karşı da çalışır.
Yetkilendirmenin sinsi yanı, kimlik doğrulamanın (Bölüm 12) başarılı olduğu yerde başlamasıdır. Saldırgan geçerli bir kullanıcı olarak giriş yapmıştır — sistem onu doğru tanımıştır. Sorun, o kullanıcının yapabildikleridir. "Ben kimim?" sorusu doğru yanıtlanır; "Buna iznim var mı?" sorusu yanlış yanıtlanır ya da hiç sorulmaz. Broken Access Control'ün özü budur: erişim kararının ya eksik olması ya da yanlış yapılması.
Bu bölüm, nesne düzeyi/yatay erişimi (bir kullanıcının başka bir kullanıcının verisine erişmesi) Bölüm 15'e (IDOR) bırakıp, yetkilendirme modeline ve özellikle dikey yükseltmeye (düşük yetkiden yüksek yetkiye) ve fonksiyon düzeyi erişim kontrolüne odaklanır.
2. Temel Teori
AuthZ, authN'den sonra gelir. Zincir: önce kimlik doğrula (kim?), sonra yetkilendir (neye izin var?). İkisini karıştırmak yaygın bir hatadır. "Giriş yapmış olmak" bir şeye izin vermez; her hassas işlem, o kullanıcının o işlem için yetkili olup olmadığını ayrıca sorgulamalıdır.
İki yükseltme türü: - Dikey yetki yükseltme: Düşük yetkili bir kullanıcının yüksek yetkili işlevlere erişmesi (kullanıcı → admin). Genelde fonksiyon düzeyi erişim kontrolü eksikliğinden doğar. (Bu bölüm.) - Yatay yetki yükseltme: Aynı yetki düzeyindeki bir kullanıcının başka bir kullanıcının kaynağına erişmesi (kullanıcı A → kullanıcı B'nin verisi). Genelde nesne düzeyi erişim kontrolü eksikliğinden (IDOR) doğar. (Bölüm 15.)
Erişim kontrol modelleri:
| Model | Karar temeli | Örnek |
|---|---|---|
| DAC (Discretionary) | Kaynak sahibi karar verir | Dosya paylaşımı izinleri |
| RBAC (Role-Based) | Kullanıcının rolü | admin / editor / user |
| ABAC (Attribute-Based) | Kullanıcı+kaynak+bağlam öznitelikleri | "aynı departman ve mesai saatinde" |
| ReBAC (Relationship-Based) | İlişki grafiği | "belgenin sahibi veya editörü" |
Çoğu web uygulaması RBAC ile başlar; karmaşıklaştıkça ABAC/ReBAC öğeleri ekler. Model seçimi önemlidir ama asıl mesele modelin doğru zorlanmasıdır.
İki temel ilke (Bölüm 3'ten): - Complete mediation (tam aracılık): Her erişim, her seferinde denetlenir. Önbelleğe alınmış veya "bir kez kontrol ettik" varsayan yetki kararları tehlikelidir. - Fail secure / deny by default (güvenli başarısızlık): Aksi açıkça belirtilmedikçe erişim reddedilir. Yeni bir uç nokta eklendiğinde birinin izin vermeyi unutması, açığa değil yalnızca erişim engeline yol açar. Tersi (izin-varsayılan) felakettir.
Kök neden. Broken Access Control neredeyse her zaman şu üçünden biridir: (1) kontrol eksik (uç nokta hiç korunmamış); (2) kontrol istemcide (buton gizlemek ≠ güvenlik); (3) kontrol yanlış değere uygulanmış (Bölüm 11'deki WordPress CVE). Üçü de aynı ilkeyle çözülür: yetkiyi sunucuda, her istekte, doğru nesne/eylem üzerinde, deny-by-default ile zorla.
3. Mimarisel Bakış
GÜVENSİZ (dağınık / istemci-taraflı / eksik kontrol):
İstek → Controller → doğrudan işlem
↑ yetki kontrolü YOK veya sadece UI'da "admin butonu gizli"
→ forced browsing: /admin/deleteUser?id=5 doğrudan çağrılır
GÜVENLİ (merkezî, sunucu-taraflı, deny-by-default):
İstek
↓
[ authN: kim? ] (Böl. 12)
↓
[ authZ katmanı: bu kullanıcı + bu eylem + bu nesne için yetkili mi? ]
↓ ← deny by default: açıkça izin yoksa 403
↓ ← her istekte, sunucuda, GERÇEK nesne üzerinde
İzin varsa → işlem | yoksa → 403 Forbidden
KRİTİK TUZAK (yanlış değere kontrol — WP CVE):
Yetki kontrolü → değer X üzerinde yapılır
Asıl işlem → değer Y üzerinde çalışır (X ≠ Y → atlatma)
Güvenli tasarımın sırrı, yetkilendirmeyi controller'lara dağıtmak yerine tek bir zorlanan katmanda (middleware/policy) toplamak ve kararı gerçekten işlenecek nesne/eylem üzerinde vermektir.
4. Güvensiz Kod
Gerçekçi bir yönetim/hesap uç noktası kümesi:
<?php
// ⚠️ GÜVENSİZ — çoklu erişim kontrolü hatası
declare(strict_types=1);
// 1) Fonksiyon düzeyi kontrol EKSİK — forced browsing
// routes: GET /admin/users/delete?id=...
$pdo->prepare('DELETE FROM users WHERE id = ?')->execute([(int)$_GET['id']]);
// admin mi diye HİÇ sorulmadı → herhangi biri çağırabilir
// 2) İstemci-taraflı "güvenlik"
// (frontend admin butonunu gizliyor ama backend kontrol etmiyor)
if ($_POST['action'] === 'promote') {
$pdo->prepare('UPDATE users SET role = "admin" WHERE id = ?')
->execute([(int)$_POST['id']]);
}
// 3) Rolü kullanıcıdan al (kendi yetkisini belirliyor — Böl. 4 mass assignment)
$_SESSION['role'] = $_POST['role'] ?? 'user';
// 4) Yetki kararı "yanlış değere" (type juggling ile atlatılabilir)
$postId = (int)$_GET['id']; // işlem bu değerle
if (current_user_can_edit($_GET['id'])) { // kontrol farklı değerle
updatePost($postId, $_POST['content']);
}
5. Açığın Analizi
DELETE ... WHERE id = ? (kontrol eksik) — Missing function-level access control. Uç nokta hiçbir yetki kontrolü yapmıyor. Rotayı bilen herhangi bir kullanıcı (hatta kimlik doğrulamasız, rotaya göre) kullanıcı silebilir. Bu, "forced browsing"in klasik hedefidir: saldırgan /admin/... yollarını tahmin/keşfeder ve doğrudan çağırır. UI'da link olmaması koruma değildir.
İstemci-taraflı gizleme — Frontend admin butonunu gizlese de, backend promote eylemini kontrolsüz işliyor. İstemci tarafı asla bir güven sınırı değildir (Bölüm 1). Saldırgan isteği elle oluşturur; UI'ın ne gösterdiği önemsizdir.
$_SESSION['role'] = $_POST['role'] — Kullanıcı kendi rolünü belirliyor: doğrudan dikey yetki yükseltme (ve mass assignment, Bölüm 4). Rol asla kullanıcı girdisinden gelmez; sunucu, kimliğe göre atar.
Yetki kararı yanlış değere — En sinsi hata. Kontrol $_GET['id'] üzerinde (ham dize), işlem (int)$_GET['id'] üzerinde (tam sayı). İkisi farklıysa (type juggling: "456ABC" → kontrol başka, (int) başka), saldırgan kontrolü bir nesne için geçip başka bir nesneyi değiştirir. Bu tam olarak WordPress CVE-2017-1001000'in (Bölüm 11) mekanizmasıdır.
Kök sorun: yetki ya hiç kontrol edilmiyor, ya istemcide, ya kullanıcı girdisinden, ya da işlenen nesneden farklı bir değer üzerinde. Dördü de sunucu-taraflı, doğru-nesne, deny-by-default zorlamayla çözülür.
6. Hacker Bakış Açısı
Saldırgan erişim kontrolünü nasıl hedefler?
Yatay ve dikey haritalama yapar. Düşük yetkili bir hesapla giriş yapıp, yüksek yetkili işlevlere (admin panelleri, kullanıcı yönetimi, ayarlar) doğrudan erişmeyi dener. UI'da görünmeyen ama var olan uç noktaları tahmin eder (/admin, /api/users, /settings/roles) — buna forced browsing denir.
İstemci kısıtlamalarını atlar. UI bir butonu gizliyorsa, saldırgan ilgili isteği doğrudan (curl/Burp) gönderip backend'in gerçekten kontrol edip etmediğini test eder. Çoğu Broken Access Control, "UI gizledi, backend kontrol etmedi" boşluğundadır.
Rol/kimlik metaverisini kurcalar. Rolü taşıyan her şeyi (gizli form alanı, cookie, JWT claim'i, X-Role başlığı) değiştirmeyi dener. İstemci tarafında saklanan veya imzasız bir rol taşıyıcısı, doğrudan yükseltme vektörüdür.
Kontrol ile işlem arasındaki tutarsızlığı arar. İleri düzey saldırgan, yetki kontrolünün hangi değer üzerinde yapıldığını ve işlemin hangi değeri kullandığını inceler. İkisi arasında bir dönüşüm (cast, normalize, trim) varsa, kontrolü bir nesne için geçip başka nesneye ulaşmayı dener (WP CVE mantığı).
Metot/HTTP fiili değiştirir. Bir uç nokta GET için korunup POST/PUT için korunmamış olabilir; ya da bir API farklı bir içerik tipiyle farklı davranabilir. Saldırgan bu tutarsızlıkları yoklar.
Savunmacı dersi: Saldırgan "erişebildiğim ama erişmemem gereken" her şeyi sistematik arar. Tek savunma, her hassas eylemde — istisnasız — sunucu tarafında yetki zorlamaktır.
7. Exploit Mantığı
Bu bölüm çalıştırılabilir saldırı içermez. Broken Access Control'ün neden bu kadar etkili olduğu kavramsaldır:
- Doğrudan etki. Erişim kontrolü atlatıldığında ara aşama yoktur; saldırgan doğrudan yetkisiz eylemi yapar (veri okuma/değiştirme/silme, yükseltme). Bu yüzden OWASP #1'dir: hem yaygın hem doğrudan yıkıcı.
- Dikey yükseltme = tam devir. Bir kullanıcı admin işlevlerine ulaşabiliyorsa, sistemin tüm kontrolünü kazanır; kullanıcı yönetimi, ayarlar, hatta (eklenti/shortcode zinciriyle) kod çalıştırma (WP CVE'de olduğu gibi).
- Sessizlik ve ölçek. Yetkisiz erişim meşru istek gibi göründüğünden fark edilmeyebilir; otomatikleştirilince tek bir açık binlerce kaydı etkiler (WP CVE'de tek istekle herhangi bir yazı değiştirilebiliyordu).
- Zincir başlangıcı. Broken Access Control sıklıkla başka açıkların (yüklenen web shell'e erişim, ayrıcalıklı bir işlevle SQLi/RCE) kapısını açar.
Araştırmacının çerçevesi: (a) yetki kontrolü var mı, (b) sunucuda mı istemcide mi, (c) doğru nesne/eylem üzerinde mi. Savunma, üçünü de "sunucuda, her istekte, doğru nesnede, deny-by-default" ile kapatır.
8. Güvenli Kod
Merkezî, sunucu-taraflı, deny-by-default yetkilendirme:
<?php
// ✅ GÜVENLİ — merkezî policy, deny-by-default, doğru nesne
declare(strict_types=1);
/**
* Basit bir yetki kapısı (framework'ler bunu policy/voter olarak sunar).
* Deny-by-default: eşleşen bir izin kuralı yoksa reddet.
*/
final class Gate {
public function __construct(private User $user) {}
public function authorize(string $ability, mixed $resource = null): void {
if (!$this->allows($ability, $resource)) {
http_response_code(403);
throw new AccessDeniedException("İzin yok: $ability");
}
}
private function allows(string $ability, mixed $resource): bool {
return match ($ability) {
'user.delete', 'user.promote' => $this->user->role === 'admin',
'post.edit' => $resource instanceof Post
&& ($this->user->role === 'admin'
|| $resource->authorId === $this->user->id),
default => false, // ← DENY BY DEFAULT
};
}
}
// 1) Fonksiyon düzeyi kontrol — her hassas eylemde
$gate->authorize('user.delete');
$pdo->prepare('DELETE FROM users WHERE id = ?')->execute([(int)$_POST['id']]);
// 2) Rol ASLA kullanıcıdan gelmez — sunucu, kimliğe göre atar
// ($_SESSION['role'] girişte DB'den okunur, istekten değil)
// 3) Yetki kararı ile işlem AYNI nesne üzerinde
$postId = (int)$_POST['id']; // tek, kanonik değer
$post = Post::findOrFail($postId); // gerçek nesneyi getir
$gate->authorize('post.edit', $post); // kontrol GERÇEK nesne üzerinde
updatePost($post->id, $_POST['content']); // işlem AYNI nesne üzerinde
Framework araçları — elle Gate yazmak yerine:
// Laravel — Policy + Gate; controller'da:
$this->authorize('update', $post); // Post için UpdatePolicy çalışır
// veya route middleware: ->middleware('can:update,post')
// Symfony — Voter:
$this->denyAccessUnlessGranted('EDIT', $post); // PostVoter karar verir
Öne çıkan modern kalıplar:
- Merkezî yetkilendirme: Laravel Policy/Gate, Symfony Voter. Kararı controller'a dağıtmak yerine tek, test edilebilir, zorlanan bir katmanda topla.
- Deny by default: Eşleşen açık izin yoksa reddet (default => false).
- Sunucu tarafında zorla: UI gizleme yalnızca UX'tir; güvenlik backend'dedir.
- Rol sunucudan: $_SESSION['role'] girişte kimliğe göre atanır; istekten asla.
- Doğru nesne üzerinde: Önce gerçek nesneyi getir, yetkiyi onun üzerinde ver, sonra aynı nesneyle işlem yap — kontrol/işlem tutarsızlığını (WP CVE) kapat.
- Her istekte: Middleware ile, her hassas rotada zorunlu.
9. Patch Analizi
Neden işe yarar? Merkezî policy + deny-by-default, "kontrol etmeyi unutma" hatasını yapısal olarak imkânsız kılar: yeni bir yetenek tanımlanmadıkça reddedilir. Kararın gerçek nesne üzerinde verilmesi, kontrol/işlem tutarsızlığını (type juggling atlatması) kapatır. Sunucu-taraflı zorlama, istemci manipülasyonunu anlamsızlaştırır. Bunlar Bölüm 3'ün "complete mediation" ve "fail secure" ilkelerinin doğrudan uygulanışıdır.
Alternatiflerin karşılaştırması:
| Yaklaşım | Değerlendirme |
|---|---|
| Kontrolsüz uç nokta | Kritik (OWASP #1) |
| İstemci-taraflı gizleme | Güvenlik değil; atlatılır |
Controller'a dağıtık if role== |
Kırılgan; biri unutulur; deny-by-default yok |
| Merkezî Policy/Voter + deny-by-default | Önerilen; test edilebilir, tutarlı |
| ABAC/ReBAC (karmaşık ihtiyaçlar) | Gerektiğinde; öznitelik/ilişki temelli |
Performans: Yetki kontrolü tipik olarak birkaç karşılaştırma veya bir sahiplik sorgusudur; maliyeti ihmal edilebilir. İlişki tabanlı (ReBAC) kararlar ek sorgu getirebilir; bu, önbelleğe dikkatle alınır (complete mediation'ı bozmadan). Güvenlik kazancı her durumda maliyetin çok üzerindedir.
10. Gerçek Hayat Senaryosu
Kurgu — bir kurumsal İK (HR) SaaS'ı. Uygulama, "maaş bordrosunu görüntüle/düzenle" işlevini yalnızca İK rolüne UI'da gösteriyor; ama /api/payroll/{id} uç noktası backend'de rol kontrolü yapmıyor (fonksiyon düzeyi kontrol eksik). Sıradan bir çalışan, tarayıcı geliştirici araçlarıyla API çağrısını görüp doğrudan tekrar oynatıyor ve tüm çalışanların maaş verisine erişiyor — hatta kendi maaşını "düzenliyor". Ek olarak, kayıt sırasında role alanı kullanıcı girdisinden alındığından, saldırgan kaydolurken role=hr_admin göndererek kalıcı yükseltme sağlıyor. Dersler: (1) UI gizleme güvenlik değildir; her API uç noktası backend'de yetki zorlamalıdır; (2) rol asla kullanıcı girdisinden gelmez; (3) hem dikey (rol yükseltme) hem fonksiyon-düzeyi (korunmasız uç nokta) kontroller birlikte gerekir.
11. Gerçek CVE Analizi — WordPress REST API Yetki Yükseltme (CVE-2017-1001000)
Sucuri'nin (Marc-Alexandre Montpas) analizi, WordPress çekirdek güvenlik notları ve MITRE/NVD/WPScan ile doğrulanmıştır. Silahlaştırılmış payload verilmez.
Özet. WordPress 4.7.0 ve 4.7.1'de, REST API'de kimlik doğrulaması gerektirmeyen bir yetki yükseltme (içerik enjeksiyonu) açığı bulundu. REST API bu sürümlerde öntanımlı etkin olduğundan, saldırgan sitedeki herhangi bir yazı veya sayfanın içeriğini kimlik doğrulaması olmadan değiştirebiliyordu. Sucuri tarafından bulunup WordPress güvenlik ekibine bildirildi; 4.7.2'de sessizce düzeltildi (kullanıcılara yama süresi tanımak için gecikmeli açıklandı).
Teknik neden — "yetki kontrolü yanlış değere" hatasının ders kitabı örneği. WordPress'in yazı güncelleme uç noktası, kullanıcının o yazıyı düzenleme yetkisi olup olmadığını kontrol ediyordu. Ancak id parametresi işlenirken bir tutarsızlık vardı: WordPress, yetki kontrolünü bir değer üzerinde yaparken, asıl yazıyı getirmek için id'yi tam sayıya cast ediyordu. PHP'nin tip dönüşümü nedeniyle (int)"456ABC" ifadesi 456 verir. Böylece saldırgan /wp-json/wp/v2/posts/123?id=456ABC gibi bir istekle: yetki kontrolünü bir yazı bağlamında geçirip, (int) cast'i sayesinde asıl güncellemeyi 456 numaralı (yani izni olmadığı) yazıda gerçekleştirebiliyordu. Kontrolün yapıldığı değer ile işlemin uygulandığı değer ayrıştı — ve bu ayrışma, tam erişim kontrolü atlatmasına yol açtı.
Bu vaka iki dersi birleştirir: type juggling (Bölüm 1) ve broken access control. Asıl hata kriptografik değil, yetki kararının işlenen gerçek nesneden farklı bir değere uygulanmasıdır (bkz. Bölüm 5, dördüncü hata). Doğru tasarım — önce nesneyi kanonik değerle getir, yetkiyi o nesne üzerinde ver, sonra aynı nesneyle işlem yap — bu ayrışmayı imkânsız kılardı.
Etki. Kimlik doğrulamasız, uzaktan, herhangi bir içeriğin değiştirilmesi. Saldırganlar bunu SEO spam, defacement ve — kurulu eklentilere/shortcode'lara bağlı olarak — kod çalıştırmaya tırmandırdı. Tek bir otomatik saldırı binlerce yazıyı değiştirebiliyordu; WordPress'in yaygınlığı nedeniyle kitlesel sömürüldü.
Çıkarılacak dersler: 1. Yetki kararı, işlenecek gerçek nesne/değer üzerinde verilmelidir. Kontrol ile işlem farklı değerlere bakarsa, aradaki her dönüşüm (cast/normalize) bir atlatma yaratır. 2. Type juggling yalnızca kimlik doğrulamayı değil (Bölüm 12), yetkilendirmeyi de kırar. Güvenlik kararı veren her yerde tip/dönüşüm titizliği şarttır. 3. Öntanımlı etkin özellikler saldırı yüzeyidir. REST API'nin varsayılan açık olması, açığın etkisini devasa büyüttü (secure by default, Bölüm 3).
12. Detection
Kod incelemede: Her hassas uç noktada yetki kontrolünün varlığını, yerini ve hangi değere uygulandığını arayın:
# Yetki kontrolü olmadan hassas işlem yapan uç noktalar
grep -rnE '(DELETE|UPDATE|INSERT).*users|role\s*=' src/ | grep -v authorize
grep -rn 'is_admin\|can(\|authorize\|denyAccessUnless' src/ # kontrollerin yeri
grep -rnE '\(int\)\$_(GET|POST|REQUEST)' src/ # cast/işlem tutarsızlığı olabilir
grep -rn '_POST\[.role.\]\|_GET\[.role.\]' src/ # rol kullanıcıdan mı?
Her hassas uç nokta için: sunucu-taraflı yetki var mı? Deny-by-default mi? Kontrol ile işlem aynı nesne üzerinde mi?
SAST: Eksik yetkilendirme (CWE-862), hatalı yetkilendirme (CWE-863) ve kullanıcı-kontrollü rol atama için kurallar. Framework-farkında araçlar, policy/voter çağrısı olmayan hassas rotaları işaretleyebilir.
DAST: İki hesapla (düşük/yüksek yetki) test ederek yatay/dikey erişimi otomatik dener; forced browsing için bilinen admin yollarını yoklar. Erişim kontrolü testi, çok hesaplı DAST'ın en güçlü olduğu alandır.
Loglar/SIEM: Düşük yetkili bir hesabın admin uç noktalarına erişim denemeleri; tek kullanıcının çok sayıda farklı nesneye sıralı erişimi (numaralandırma); 403'lerdeki ani artış (forced browsing taraması) ya da 403 beklenirken 200 dönen uç noktalar. Yetkisiz-erişim korelasyonları en değerli SIEM içeriklerindendir.
13. Prevention
- Deny by default: Açık izin yoksa reddet; yeni uç nokta güvenli tarafta başlar (Bölüm 3).
- Sunucu tarafında zorla: UI gizleme güvenlik değildir; her hassas eylem backend'de kontrol edilir.
- Merkezî yetkilendirme: Laravel Policy/Gate, Symfony Voter; dağıtık
ifyerine tek, test edilebilir katman. - Doğru nesne üzerinde karar: Önce kanonik değerle gerçek nesneyi getir, yetkiyi onun üzerinde ver, aynı nesneyle işlem yap (WP CVE dersi).
- Rol sunucudan: Kullanıcı girdisinden rol/yetki alma (mass assignment, Bölüm 4).
- Complete mediation: Her istekte kontrol; yetki kararlarını dikkatsizce önbelleğe alma.
- Test et: Erişim kontrolü için çok-hesaplı otomatik testler (düşük yetkili → yüksek işlev → 403 beklenir).
- Threat modeling: STRIDE "Elevation of Privilege" merceğini her yeni işleve uygula (Bölüm 2).
14. Mitigation
- Acil: Korunmasız hassas uç noktalara sunucu-taraflı yetki kontrolü ekle; kullanıcıdan rol alan akışları kapat; WAF'ta admin yollarına geçici erişim kısıtı.
- Geçici: Loglardan yetkisiz erişim kapsamını belirle; yükseltilmiş hesapları ve değiştirilmiş kayıtları tespit edip düzelt; şüpheli oturumları iptal et.
- Kalıcı: Yetkilendirmeyi merkezî policy/voter katmanına taşı; deny-by-default'u zorunlu kıl; kontrol/işlem tutarlılığını düzelt; çok-hesaplı erişim testleri ekle.
15. Checklist
- [ ] Her hassas uç nokta sunucu tarafında yetki kontrolü yapıyor mu?
- [ ] Yetkilendirme merkezî mi (Policy/Voter/middleware), dağıtık
ifdeğil mi? - [ ] Deny-by-default uygulanıyor mu (eşleşen izin yoksa reddet)?
- [ ] Yetki kararı, işlenecek gerçek nesne/değer üzerinde mi veriliyor (kontrol/işlem tutarlı mı)?
- [ ] Rol/yetki kullanıcı girdisinden alınmıyor mu (mass assignment yok)?
- [ ] İstemci-taraflı gizleme güvenlik olarak sayılmıyor mu; backend gerçekten kontrol ediyor mu?
- [ ] Her istekte kontrol var mı (complete mediation); yetki önbelleği güvenli mi?
- [ ] Çok-hesaplı otomatik erişim kontrolü testleri var mı?
16. Laboratuvar
Lab 14.1 — Forced browsing. İzole bir uygulamada UI'da gizli ama korunmasız bir /admin/... uç noktası kur; düşük yetkili bir hesapla doğrudan çağırıp erişebildiğini gözlemle. Sunucu-taraflı yetki kontrolü ekleyip 403'ü doğrula.
Lab 14.2 — İstemci vs sunucu. Frontend'de admin butonunu gizle ama backend kontrolünü ekleme; isteği elle (curl) gönderip eylemin gerçekleştiğini gözlemle. Backend kontrolü ekleyip farkı gör.
Lab 14.3 — Kontrol/işlem tutarsızlığı (WP CVE). Yetki kontrolünü $_GET['id'], işlemi (int)$_GET['id'] üzerinde yapan bir uç nokta yaz; "5ABC" ile ayrışmayı göster. Sonra "önce nesneyi getir, onun üzerinde yetki ver" kalıbıyla düzelt.
Lab 14.4 — Rol enjeksiyonu. Kayıt akışında role alanını kullanıcıdan alan bir kod yaz; role=admin ile yükseltmeyi göster. Rolü sunucuda sabitleyip düzelt.
17. Quiz
- AuthZ, authN'den nasıl farklıdır ve neden ondan sonra gelir?
- Dikey ve yatay yetki yükseltme arasındaki fark nedir? Hangisi IDOR'dur (Bölüm 15)?
- RBAC, ABAC ve ReBAC modellerini kısaca açıklayın.
- "Deny by default" (fail secure) ilkesi bir yeni uç nokta eklendiğinde neyi garanti eder?
- "Complete mediation" nedir ve yetki önbelleği neden dikkat gerektirir?
- İstemci-taraflı gizleme neden bir güvenlik kontrolü değildir?
- "Yetki kontrolünün yanlış değere uygulanması" ne demektir? WordPress CVE-2017-1001000 bunu nasıl örnekler?
- Type juggling yalnızca kimlik doğrulamayı mı kırar? Yetkilendirmede nasıl rol oynar?
- Rolü kullanıcı girdisinden almak neden tehlikelidir? (Bölüm 4'e atıfla.)
- Merkezî yetkilendirme (Policy/Voter), dağıtık
ifkontrollerinden neden üstündür? - Forced browsing nedir ve nasıl savunulur?
- Erişim kontrolü testinde neden çok-hesaplı DAST gereklidir?
18. Kaynakça
- OWASP, Top 10:2021 — A01 Broken Access Control; Authorization Cheat Sheet; Access Control Cheat Sheet.
- MITRE, CWE-862: Missing Authorization; CWE-863: Incorrect Authorization; CWE-269: Improper Privilege Management; CWE-284: Improper Access Control.
- MITRE / NVD / WPScan, CVE-2017-1001000 (WordPress REST API privilege escalation).
- Sucuri (Marc-Alexandre Montpas), Content Injection Vulnerability in the WordPress REST API teknik analizi.
- Laravel dokümantasyonu, Authorization (Gates & Policies); Symfony dokümantasyonu, Security Voters.
- NIST, RBAC (INCITS 359) ve ABAC (SP 800-162) rehberleri.