JWT Nedir? Yaygın Zayıflıkları ve CTF'te İncelenmesi
JWT (JSON Web Token), modern web uygulamalarında "sen kimsin ve neyi yapabilirsin" bilgisini taşıyan küçük bir bilettir. Bu rehberde JWT'nin nasıl parçalandığını sıfırdan öğrenecek, en sık görülen iki zafiyeti (alg=none ve zayıf HS256 sırrı) örneklerle çözecek ve bunların nasıl fark edilip önlendiğini göreceksin.
- JWT üç parçadan oluşur: header.payload.signature, noktayla ayrılır ve ilk iki parça base64url ile herkese açık şekilde okunur.
- base64url çözmek şifre kırmak değildir; payload'ı okumak yetki almak anlamına gelmez, imzayı geçmek gerekir.
- alg=none, sunucu imza kontrolünü kapatırsa token'ı imzasız kabul etmesine dayanır.
- Zayıf bir HS256 sırrı (örn. 'secret', '123456') wordlist ile kırılıp geçerli token üretmeye izin verebilir.
- Savunma: alg'yi sabitle, güçlü ve uzun sır kullan, imzayı her zaman doğrula.
Bir siteye giriş yaptığında sunucu sana bir "bileti" verir: bundan sonra her istekte bu bileti gösterirsin, sunucu da her seferinde kullanıcı adı/şifre sormak yerine bileti kontrol eder. JWT tam olarak bu bilettir. Sorun şu ki, bu bilet çoğu zaman şifreli değildir — sadece imzalıdır. Bu ayrımı anladığında JWT zafiyetlerinin çoğu netleşir.
JWT tam olarak nedir?
Bir JWT üç parçadan oluşur ve parçalar nokta (.) ile ayrılır:
header . payload . signature
▲ ▲ ▲
algoritma veri imza
- header: Hangi imza algoritmasının kullanıldığını söyler (örn.
HS256,RS256). - payload: Asıl veri. Kullanıcı adı, rol, geçerlilik süresi gibi bilgiler burada durur.
- signature: header + payload'ın, gizli bir sır ile üretilmiş imzası. Token'ın kurcalanmadığını kanıtlar.
Kritik nokta: header ve payload şifrelenmez, sadece base64url ile kodlanır. Yani token'ı ele geçiren herkes içindeki veriyi okuyabilir. Gizlilik değil, bütünlük korunur — imza sayesinde payload'ı değiştirirsen imza tutmaz.
Bir JWT'yi elle çözmek: base64url
Bir token'ın ilk parçasını (header) çözelim. base64url, normal base64'ün web-güvenli hâlidir. Terminalde şöyle bakabilirsin:
echo 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9' | base64 -d
# çıktı: {"alg":"HS256","typ":"JWT"}
Gördüğün gibi header, imzanın HS256 algoritmasıyla üretildiğini söylüyor. Payload parçası için de aynı şeyi yaparsın; çoğunlukla {"role":"user"} gibi bir veri görürsün. Dikkat: base64url'da + yerine -, / yerine _ kullanılır ve sondaki = dolgusu atılmış olabilir; bazı token'ları çözerken sona = eklemen gerekebilir. base64url çözmek asla "şifre kırmak" değildir — sadece okunur hâle getirmektir.
Zayıflık 1: alg=none
JWT standardı, teoride imzasız bir token tipine de izin verir: alg alanı none olduğunda imza yoktur. Hatalı yazılmış bir sunucu bu durumu reddetmek yerine token'ı "imzalı gibi" kabul ederse büyük sorun çıkar.
Mantık şu: saldırgan header'ı {"alg":"none"} yapar, payload'daki "role":"user" değerini "role":"admin" olarak değiştirir ve imza parçasını tamamen boş bırakır. Zafiyetli sunucu imzayı kontrol etmediği için bu sahte token'ı geçerli sayar.
Bunu yalnızca yetkili/eğitim ortamlarında ve CTF laboratuvarlarında denemelisin. Bir CTF'te fark etme refleksin şu olmalı: token'daki alg değerine bak, none denemesi kabul ediliyor mu diye test et. Bu tür web tabanlı token zafiyetlerini pratik etmek için web kategorisi challenge'larına göz atabilirsin.
Zayıflık 2: Zayıf HS256 sırrı
HS256 simetrik bir algoritmadır: imzayı üreten sır ile doğrulayan sır aynıdır. Eğer geliştirici bu sırrı secret, password ya da 123456 gibi tahmin edilebilir bir şey yaptıysa, saldırgan bu sırrı bir kelime listesiyle deneyerek bulabilir.
Mantığı şöyle: token'ın header ve payload'ı zaten açık. Saldırgan bir wordlist'teki her kelimeyi sır olarak varsayıp aynı imzayı üretmeye çalışır; imza token'daki imzayla eşleşen kelime, gerçek sırdır. Sır bulununca artık istediğin payload'ı (örneğin admin rolü) geçerli imzayla üretebilirsin.
Bu iş için CTF'lerde sık kullanılan araçlar jwt_tool ve hashcat'tir (HS256 için hashcat modu 16500). Yine hatırlatalım: bu teknikler sadece sana ait ya da izinli laboratuvar sistemlerinde denenir.
CTF'te JWT'yi nasıl incelersin?
Bir web challenge'ında token gördüğünde izleyebileceğin basit bir yol haritası:
- Tanı: Üç parçalı, noktayla ayrılmış,
eyJile başlayan bir string gördüysen bu büyük ihtimalle bir JWT'dir. - Oku: header ve payload'ı base64url ile çöz.
algne? Payload'darole,isAdmingibi ilginç alanlar var mı? - Test et:
alg=nonekabul ediliyor mu? Sır zayıf olabilir mi? İmza gerçekten kontrol ediliyor mu? - Üret: Zafiyet doğrulandıysa hedeflediğin payload ile yeni bir token oluştur ve isteği tekrar gönder.
Bu adımları uygularken sabırlı ol; çoğu challenge tek bir küçük detaya (yanlış çözülmüş base64, kontrol edilmeyen imza) dayanır. Konuya baştan bakmak istersen CTF Nedir? sayfasına, kategori kategori çalışma planı için de Rehber ana sayfasına göz atabilirsin.
Peki nasıl korunulur?
Saldırıyı anlamak savunmayı da öğretir. Bir uygulama geliştiriyorsan JWT'yi güvenli kullanmanın temelleri şunlardır:
- Algoritmayı sabitle: Sunucu yalnızca beklediğin algoritmayı (örn. sadece
HS256) kabul etsin;algalanına asla körü körüne güvenme venone'ı reddet. - Güçlü sır kullan: HS256 sırrı uzun, rastgele ve tahmin edilemez olsun; kod içine gömülü sabit "secret" bırakma.
- İmzayı her zaman doğrula: Payload'daki role/yetki bilgisine, imza geçerliliğini kontrol etmeden asla güvenme.
- Süre koy:
expile token'a kısa geçerlilik süresi ver; çalınan bir token sonsuza dek geçerli olmasın.
Özetle JWT, doğru kullanıldığında sağlam; ama küçük bir yanlış (kontrol edilmeyen imza ya da zayıf bir sır) tüm oturum güvenliğini çökertebilir. Bu mantığı bir kez kavradığında, bir sonraki adım pratik: öğrendiğin tekniği web challenge'larında kendi ellerinle dene.
Sıkça Sorulan Sorular
JWT şifreli midir, yoksa herkes içindekini okuyabilir mi?
Standart JWT şifreli değildir; sadece imzalıdır. Header ve payload base64url ile kodlanır, bu da isteyen herkesin içeriği okuyabileceği anlamına gelir. Gizli kalmasını istediğin hassas veriyi (parola, TCKN gibi) asla payload'a koymamalısın.
Bir JWT'nin payload'ını çözebiliyorsam sistemi hacklemiş olur muyum?
Hayır. base64url çözmek sadece veriyi okunur hâle getirir, bir yetki kazandırmaz. Gerçek erişim için imzayı geçmen gerekir; bu da ya alg=none gibi bir mantık hatası ya da zayıf bir sır bulmayı gerektirir.
alg=none nedir ve neden tehlikeli?
alg=none, imzasız token anlamına gelen bir JWT ayarıdır. Sunucu imza kontrolünü doğru yapmazsa, saldırgan payload'ı istediği gibi (örneğin rolü admin yaparak) değiştirip imzayı boş bırakabilir. İyi yazılmış bir sunucu none algoritmasını reddeder.
Bu teknikleri gerçek web sitelerinde denemek yasal mı?
Hayır. İzinsiz sistemlere saldırmak suçtur. Bu teknikler yalnızca sana ait sistemlerde, izinli sızma testlerinde ya da Pratik gibi eğitim amaçlı CTF laboratuvarlarında denenmelidir.
JWT konusuna nereden pratik yapmaya başlamalıyım?
Önce base64url çözmeyi ve token yapısını rahatça tanıyacak kadar oyna. Ardından web kategorisindeki challenge'larda alg=none ve zayıf sır senaryolarını sırayla dene; her çözümde bir tekniği pekiştirmiş olursun.
Hadi pratiğe dök
Bu rehberdeki teknikleri Web kategorisindeki gerçek challenge’larda dene.
Web Challenge’ları →