OAuth yanlış yapılandırması
- OAuth akışını yapılandırma açısından sınarsın: redirect_uri eşleşmesi, state parametresi, PKCE zorunluluğu ve hesap devralmaya açılan kapsam hataları.
- OAuth bir yetkilendirme protokolüdür; hataların çoğu protokolde değil yapılandırmada çıkar.
- state ve PKCE, akışın iki temel koruma parçasıdır.
Puan bütün etkinlikleri cevaplayınca hesaba yazılır. Bu dersi tamamlayınca +55 XP alacaksın. Giriş yapmadan ilerlersen puan yalnız bu tarayıcıda durur.
Bir siteye başka bir hesabınla girdiğinde arka planda bir yetki akışı çalışır. Uygulama seni sağlayıcıya yönlendirir. Onay verirsin ve sağlayıcı seni geri gönderirken adrese bir yetki kodu ekler.
Uygulama o kodu arka planda jetona çevirir. Bu akışı anlamanın kolay yolu üç tarafı ayırmaktır: kullanıcı, uygulama ve sağlayıcı. Protokol, uygulamanın kullanıcı adına sınırlı erişim almasını düzenler.
Parola hiçbir zaman uygulamaya verilmez; uygulama yalnız kısa ömürlü bir yetki kodu ve ardından bir erişim jetonu görür. Bu tasarım güçlüdür ama ayrıntıya duyarlıdır. Tek bir gevşek ayar, akışın güvencesini götürür ve bu yüzden test kriptografiye değil yapılandırmaya bakar.
Geri dönüş adresi
Akışın can damarı geri dönüş adresidir. Sağlayıcı, yetki kodunu yalnız önceden kayıtlı adrese göndermelidir. Sağlayıcı kaydı sırasında tam adresi saklar ve gelen isteği bu adresle karşılaştırır.
Karşılaştırma tam eşleşme değil de önek ya da joker karakter kabul ederse, kayıtlı adresle başlayan her adres geçerli sayılır. Sağlayıcı yalnız alan adıyla başlamayı arıyorsa, panel.hedef.example.saldirgan.test gibi bambaşka bir sunucu da geçer.
Kayıtlı yolun tamamı önek olarak aranıyorsa kod aynı sunucuda kalır ama beklenmedik bir yola gider. O yolda açık yönlendirme ya da dış kaynak varsa kod bir adım sonra dışarı sızar. RFC 9700 bu yüzden tam dizgi eşleşmesini zorunlu tutar: iki adres karakter karakter aynı olmalıdır. Tek istisna, yerel uygulamaların localhost adresindeki kapı numarasıdır.
# Riskli kayıtlar redirect_uri = https://panel.hedef.example/* redirect_uri = https://panel.hedef.example/geri # önek eşleşmesi açık # Sağlam kayıt redirect_uri = https://panel.hedef.example/oauth/geri # tam eşleşme
Yetki kodunun neden bu kadar korunduğunu anlamak için akışın kalanını görmek gerekir. Sağlayıcı seni geri dönüş adresine gönderirken sorguya bir yetki kodu ekler. Uygulama bu kodu, kullanıcı görmeden, arka planda sağlayıcının jeton uç noktasına yollar ve karşılığında bir erişim jetonu alır. Yani kod, erişim jetonuna çevrilebilen kısa ömürlü bir bilettir.
Kodu ele geçiren biri, uygulamanın yerine geçip jetonu alabilir. İşte bu yüzden kod tek kullanımlıktır, en fazla birkaç dakika yaşar ve yalnız kayıtlı adrese teslim edilir. Bu üç kural birden, çalınan bir kodun işe yaramasını çok zorlaştırır.
Açık yönlendirme ile birleşen OAuth hataları özel bir sınıf oluşturur. Kayıtlı adres doğru görünür ama uygulamanın kendi içinde bir yönlendirme açığı vardır. Kod önce doğru adrese gider, sonra saldırganın adresine taşınır.
RFC 9700 bu yüzden hem istemcilerin hem sağlayıcıların, sorgu parametresinden alınan adrese körü körüne yönlendiren açık yönlendirici uç noktaları barındırmamasını ister. Yönlendiren başlığı da kod sızdırabilir.
Geri dönüş sayfası dış bir kaynak yüklüyorsa, adresteki kod o isteğin başlığında dışarı çıkar. Bu yüzden geri dönüş sayfası sıkı bir Referrer-Policy kullanır ve dış kaynak yüklemez. Kod da tek kullanımlıktır; sağlayıcı ikinci kez sunulan kodu reddeder.
Etkinlik 1 / 6
OAuth yapılandırmasında zafiyetli satırı bul.
state ve istemci türü
İkinci koruma parçası state değeridir. Uygulama akışı başlatırken rastgele bir değer üretir ve oturumla eşler. Dönen yanıtta aynı değeri bekler. Bu değeri denetlemezse saldırgan kendi yetki kodunu kurbanın tarayıcısında çalıştırır ve hesapları birbirine bağlar.
Sonuç, siteler arası istek sahteciliğiyle hesap bağlamadır: kurban kendi hesabına girdiğini sanırken aslında saldırganın sağlayıcı hesabına bağlanmış olur. state değeri her akışta yeniden üretilir ve tek kullanımlıktır. RFC 9700, PKCE kullanılmıyorsa bu korumayı state ile ya da OpenID Connect nonce değeriyle sağlamayı ister.
Sağlayıcı tarafında istemci türü de doğru seçilmelidir. Gizli istemci sunucuda çalışır ve bir sır saklayabilir. Genel istemci ise tarayıcıda ya da telefonda çalışır ve sır saklayamaz, çünkü dağıtılan uygulamanın içinden çıkarılabilir. İkisini karıştırmak, sırrı herkese dağıtmak demektir.
Hesap bağlama akışları da ek dikkat ister. Var olan bir hesaba yeni bir sağlayıcı eklenirken kullanıcı yeniden doğrulanmalıdır. Aksi halde saldırgan kendi sağlayıcı hesabını kurbanın hesabına iliştirir ve kalıcı bir arka kapı açar. Bu yüzden bağlama anı da tıpkı giriş anı gibi korunur.
Kimlik doğrulama için OAuth'un üstüne bir katman daha gelir. OAuth tek başına yetkilendirmeyi çözer, yani uygulamanın kaynağa erişmesini düzenler; sen kimsin sorusunu doğrudan yanıtlamaz.
Kimlik için OpenID Connect katmanı eklenir ve sağlayıcı, erişim jetonunun yanında bir kimlik jetonu döndürür. Bu ayrımı bilmek yaygın bir hatayı da açığa çıkarır: bazı uygulamalar erişim jetonunun varlığını kullanıcının kimliği sanır. Oysa erişim jetonu bir kaynağa erişim biletidir, kim olduğunun kanıtı değildir. Kimlik jetonu ise imzalanır ve yayıncısı, hedef kitlesi ve süresi doğrulanır; tıpkı bir JWT gibi denetlenmeden güvenilmez.
Bu iki parçayı bir arada düşünmek testin çerçevesini kurar. Yönlendirme adresi kodun nereye gideceğini, state ise dönüşün hangi oturuma bağlanacağını belirler. Biri gevşerse kod yanlış tarafa düşer, diğeri gevşerse kod yanlış oturuma bağlanır.
İkisini de tek tek denersin: adresi değiştirip kabul ediliyor mu, state değerini silip akış yine ilerliyor mu? Örtük akış, yani jetonu doğrudan adres parçasında döndüren eski yöntem, bu iki riski birden büyütür ve artık önerilmez. Güvenli varsayılan, kodun kısa ömürlü ve tek kullanımlık olduğu yetkilendirme kodu akışıdır.
Etkinlik 2 / 6
state parametresi OAuth akışında neyi engeller?
Bu iki parçanın ötesinde, OAuth güvenliği bir dizi küçük yapılandırma kararının toplamıdır. Her kararın güvenli bir varsayılanı ve ona karşılık gelen riskli bir sapması vardır. Tam eşleşen yönlendirme adresi güvenlidir; joker karakter içeren adres değildir. Genel istemcide PKCE zorunludur; onu atlamak açık kapı bırakır.
Jetonu adres parçasında taşıyan örtük akış eski ve risklidir; kod akışı güvenli seçimdir. Bu ayrımları bir tabloda görmek, üretimdeki ayarları hızlı okumana yarar. Aşağıdaki alıştırmada her yapılandırmayı doğru kovaya koy ve güvenli varsayılanı zihnine yerleştir.
Etkinlik 3 / 6
Her yapılandırmayı güvenli ya da riskli kovasına koy.
Önce bir seçeneğe, sonra aşağıdaki uygun kutuya bas. İstersen seçeneği kutuya sürükleyip bırak. Yerini değiştirmek için aynı işlemi tekrarla.
0/5 seçenek yerleşti.
PKCE ve genel istemciler
Üçüncü parça PKCE'dir. Mobil uygulama ya da tek sayfa uygulaması bir sırrı gizleyemez, bu yüzden yalnız state yeterli olmayabilir. PKCE, kodu isteyen istemciyi bir doğrulayıcı değere bağlar. İstemci akış başında gizli bir doğrulayıcı üretir, onun karma özetini yetki isteğine koyar ve kodu jetona çevirirken özgün doğrulayıcıyı gösterir.
Kod çalınsa bile, doğrulayıcı olmadan jetona çevrilemez. RFC 9700 genel istemcilerin PKCE kullanmasını zorunlu, gizli istemcilerin kullanmasını önerilen sayar ve sağlayıcının PKCE'yi desteklemesini şart koşar. Doğrulayıcı değer, adres güvenli karakterlerden en az 43, en çok 128 uzunluğunda olur. S256 dönüşümünü kullanabilen istemci onu kullanmak zorundadır, çünkü doğrulayıcıyı yetki isteğinde açığa çıkarmayan tek yöntem budur.
PKCE ile state farklı işlere yarar, biri diğerinin yerine geçmez. state akışı başlatan oturumla dönüşü eşler ve siteler arası istek sahteciliğini keser. PKCE ise ele geçirilmiş bir kodun jetona çevrilmesini engeller.
RFC 9700'e göre sağlayıcının PKCE desteğini doğrulamış bir istemci, siteler arası istek sahteciliği korumasını da PKCE'ye bırakabilir. Yine de state değeri ucuz bir ek katman olarak çoğu kurulumda kalır. Sunucunun PKCE'yi gerçekten uygulayıp uygulamadığını test edersin: doğrulayıcıyı hiç göndermeden ya da yanlış göndererek kodu jetona çevirmeyi denersin. Sunucu bunu kabul ediyorsa PKCE görünüşte açık ama işlevsizdir.
PKCE'nin bir de sürüm düşürme tuzağı vardır. RFC 9700, jeton isteğinde bir doğrulayıcı geldiyse, yetki isteğinde de bir karşılık gelmiş olmasını şart koşar. Aksi halde saldırgan, akışı PKCE'siz başlatıp jeton adımında kendi ürettiği bir doğrulayıcıyı ekleyerek korumayı devre dışı bırakabilir.
Sağlayıcı bu iki adımı birbirine bağlamazsa, PKCE etkinmiş gibi görünür ama aslında atlanır. Testte bunu, yetki isteğinde doğrulama özeti olmadan başlatıp jeton isteğine bir doğrulayıcı iliştirerek denersin. Sağlayıcı isteği reddetmiyorsa, PKCE zincirinde bir kopukluk vardır ve bu ayrı bir bulgu satırıdır.
Etkinlik 4 / 6
Mobil ve tek sayfa uygulamalarda yetki kodu hırsızlığını kapatan uzantının kısaltması: ____
Sınama, kapsam ve etki
Kapsam alanı testi çoğu kişinin atladığı bir adımdır. İstekteki kapsamı genişletip sağlayıcının onay ekranında ne gösterdiğine bakarsın. Sonra dönen jetonun kapsamını uygulamanın kendisinin de doğrulayıp doğrulamadığını sınarsın. Sağlayıcı sınırı uygulasa bile, uygulama jetonu kabul ederken beklediği kapsamı kontrol etmezse boşluk kalır.
Jeton saklama yeri de son halkadır. Erişim jetonu tarayıcıda yerel depoda tutulursa, tek bir XSS onu dışarı taşır. Kısa ömürlü jeton ve HttpOnly çerez, bu riski kabul edilebilir seviyeye indirir. Yenileme jetonu kullanılıyorsa, genel istemcilerde döndürme ya da göndericiye bağlama gibi ek koruma gerekir.
Testte nelere bakarsın? Yönlendirme adresini değiştirip kabul edilip edilmediğini denersin. state değerini silip akışın yine de devam edip etmediğine bakarsın.
Kapsam alanını genişletip sağlayıcının sınırı uygulayıp uygulamadığını sınarsın. Bunları ağ kaydıyla birlikte incelemek netlik verir, çünkü hangi parametrenin nereye gittiğini ancak orada görürsün. Yalnız arayüzden bakarak OAuth testi yapmak eksik kalır.
Bulguyu yazarken etkiyi somutlaştırırsın. Gevşek yönlendirme adresi tek başına düşük görünür; kodun saldırgana ulaştığı kanıtlanınca aynı bulgu hesap devralmaya döner ve derecesi yükselir.
# Deneme 1: kayıtlı adresin aynısı
GET /oauth/yetki?client_id=web-panel&response_type=code&state=a91f
&redirect_uri=https://panel.hedef.example/oauth/geri HTTP/1.1
Host: giris.saglayici.test
HTTP/1.1 302 Found
Location: https://panel.hedef.example/oauth/geri?code=4c1b...&state=a91f
# Deneme 2: kayıtlı adresin sonuna yol eklendi
GET /oauth/yetki?client_id=web-panel&response_type=code&state=a91f
&redirect_uri=https://panel.hedef.example/oauth/geri/../cikis HTTP/1.1
Host: giris.saglayici.test
HTTP/1.1 400 Bad Request
Geçersiz yönlendirme adresiÖrneği satır satır oku. client_id uygulamayı tanıtır, response_type=code yetkilendirme kodu akışını seçer. state=a91f, dönüşte geri gelmesi gereken rastgele değerdir.
Birinci denemede redirect_uri kayıtlı adresin aynısıdır. Sağlayıcı 302 ile kodu ve aynı state değerini bu adrese yollar; karşılaştırmanın temeli budur.
İkinci denemede adresin sonuna bir yol parçası eklenir. Sağlam bir sağlayıcı adresi karakter karakter karşılaştırır, 400 döner ve kullanıcıyı hiçbir yere yönlendirmez. Bu sağlayıcı da 302 dönseydi, kod uygulamanın çıkış sayfasına giderdi.
O sayfada açık yönlendirme varsa kod bir adım sonra dışarı çıkardı. Aynı yöntemle alt alan adı, büyük küçük harf ve sorgu parametresi değişikliklerini de tek tek denersin. Bunu yalnız kendi lab ortamında ya da yazılı iznin olan hedefte dene.
Savunma tarafında bu yanlış yapılandırmalar iz bırakır. Sağlayıcı, kayıtlı adresle eşleşmeyen bir yönlendirme isteğini reddeder ve bunu bir olay kaydına yazar; kısa sürede biriken çok sayıda eşleşme hatası bir deneme işaretidir. Aynı biçimde dönüşte beklenen state değeriyle uyuşmayan yanıtlar, bir yetki kodunun ikinci kez sunulması ve PKCE doğrulayıcısının eksik gelmesi ayrı sebep kodlarıyla kaydedilir ve bir alarma bağlanır.
Test ederken bıraktığın izler, savunma ekibinin de gördüğü izlerdir. İyi bir rapor, bulunan boşluğun yanında bu tespit fırsatını da gösterir ve düzeltmenin önceliğini yükseltir.
Etkinlik 5 / 6
Yetki isteğinde yönlendirme adresini değiştirip sağlayıcının eşleşmeyi sıkı yapıp yapmadığını sına.
İsteği tamamla ve gönder.
Etkinlik 6 / 6
Doğru mu, yanlış mı?
Yetki kodunun tek kullanımlık olması akışın güvenliğine katkı verir.
Derinleş:OAuth 2.1 ve güvenlik en iyi uygulaması
OAuth 2.0 çerçevesi 2012'de RFC 6749 ile yayımlandı, ilk tehdit modeli 2013'te RFC 6819 ile geldi. Aradan geçen sürede toplanan dersler 2025 Ocak ayında RFC 9700, yani OAuth 2.0 Güvenlik En İyi Güncel Uygulaması olarak toplandı. Bu belgede birkaç karar nettir. Örtük akış, yani erişim jetonunu doğrudan adres yanıtında döndüren yöntem, jeton sızıntısı yüzünden artık önerilmez.
Kaynak sahibi parola kimlik bilgisi akışı, yani kullanıcının parolasını doğrudan uygulamaya veren yöntem, hiç kullanılmamalıdır. Yetki kodu tek kullanımlıktır ve RFC 6749 en fazla on dakikalık ömür önerir. Hazırlık aşamasındaki OAuth 2.1 taslağı da bu kararları tek bir güncel çerçevede birleştirir: yetkilendirme kodu artı PKCE öntanımlı akış olur, örtük ve parola akışları çıkarılır. Test ederken üretimdeki ayarları bu belgelerin önerdiği varsayılanlarla karşılaştırmak, birkaç dakikada bulgu çıkarır.
Derinleş:Mix-up saldırısı ve iss parametresi
Bir uygulama birden çok kimlik sağlayıcısını destekliyorsa, karışıklık saldırısı adı verilen ince bir tuzak doğar. Saldırgan akışı bir sağlayıcıyla başlatır ama yanıtı, uygulamanın güvendiği başka bir sağlayıcıdan geliyormuş gibi gösterir. Uygulama, yetki kodunu ya da jetonu yanlış sağlayıcının uç noktasına yollarsa, kod saldırganın kontrol ettiği tarafa düşebilir. Bu saldırıya karşı 2022 Mart ayında yayımlanan RFC 9207 bir çözüm getirdi: yetki yanıtına, hangi sağlayıcının ürettiğini söyleyen bir iss parametresi eklenir.
Uygulama dönen iss değerini, akışı başlattığı sağlayıcıyla karşılaştırır ve uyuşmazsa akışı durdurur. RFC 9700, birden çok sağlayıcıyla konuşan istemcide bu saldırıya karşı bir savunmayı zorunlu tutar. Önerdiği yol iss kontrolüdür; bu mümkün değilse her sağlayıcıya ayrı bir geri dönüş adresi verilebilir. Tek sağlayıcılı basit kurulumlar bu saldırıdan etkilenmez, ama kurumsal giriş çözümleri çoğunlukla çok sağlayıcılıdır.
Okumayı istediğin sırayla sürdürebilirsin. Ders, bütün etkinlikleri cevapladığında tamamlanır.