JWT (JSON Web Token) Güvenliği: Saldırılar ve Korunma
JWT, sunucunun imzaladığı taşınabilir kimlik jetonudur; yanlış yapılandırılırsa saldırgan kendi jetonunu üretir. alg none, imza doğrulamama, anahtar karıştırma ve zayıf anahtar saldırıları, oturum sonlandırma sorunu ve güvenli JWT kontrol listesi.
Hızlı cevap: JWT (JSON Web Token), bir kullanıcının kimliğini ve yetkilerini taşıyan, sunucunun imzaladığı ve doğruladığı taşınabilir bir kimlik jetonudur. Modern web ve mobil uygulamalarda oturum yönetiminin yerini büyük ölçüde JWT aldı. Ama bir JWT yanlış yapılandırılırsa, saldırgan kendi jetonunu üretip başkasının hesabına ya da yönetici yetkisine geçebilir. En bilinen açıklar şunlardır: imzasız jetonu kabul etmek (alg: none), zayıf ya da sızmış imza anahtarı, imzayı hiç doğrulamamak ve jetonun süresini kontrol etmemek. Güvenli JWT kullanımı üç şeye dayanır: imzayı her zaman doğrulamak, güçlü ve gizli bir anahtar kullanmak ve süre ile yetki alanlarını sunucuda kontrol etmek.
JWT güçlü bir araçtır ama tehlikeli bir varsayımla gelir: "jeton imzalıysa güvenilir." Sorun, imzanın gerçekten doğrulanıp doğrulanmadığıdır. Birçok gerçek olayda sunucu, jetonun içini okur ama imzasını kontrol etmez ya da yanlış kontrol eder. Bu yazı, JWT'nin nasıl çalıştığını, en sık görülen saldırıları ve API güvenliği bağlamında doğru savunmayı anlatıyor.
JWT nasıl çalışır
Bir JWT üç parçadan oluşur, nokta ile ayrılır:
- Header (başlık): Hangi imza algoritmasının kullanıldığını söyler.
- Payload (yük): Kullanıcı kimliği, yetkiler ve süre gibi bilgileri taşır. Bu kısım şifreli değildir, sadece kodlanmıştır; herkes okuyabilir.
- Signature (imza): Header ve payload'ın, sunucunun gizli anahtarıyla imzalanmış halidir. Jeton değiştirilirse imza tutmaz.
Kritik yanılgı: payload şifreli değildir. JWT'ye asla parola, kart numarası gibi hassas veri konmaz. JWT güveni imzayla sağlar, gizlilikle değil.
En sık görülen JWT saldırıları
| Saldırı | Kök neden | Sonuç |
|---|---|---|
| alg: none kabulü | Sunucu imzasız jetonu kabul eder | Herkes geçerli jeton üretir |
| İmza doğrulamama | Payload okunur, imza kontrol edilmez | Jeton serbestçe değiştirilir |
| Zayıf HMAC anahtarı | Tahmin edilebilir gizli anahtar | Anahtar kırılır, jeton üretilir |
| Anahtar karıştırma | RS256 beklenirken HS256 kabul edilir | Açık anahtarla imza taklidi |
| Süre kontrolsüzlüğü | exp alanı kontrol edilmez | Çalınan jeton sonsuza dek geçerli |
alg: none
Bazı kütüphaneler, header'da algoritma "none" yazıyorsa jetonu imzasız kabul eder. Saldırgan payload'ı istediği gibi düzenler, imzayı boş bırakır ve yönetici olur. Sunucu, kabul edeceği algoritmayı kendisi belirlemeli, jetonun söylediğine güvenmemelidir.
Anahtar karıştırma (RS256 ve HS256)
RS256 açık ve özel anahtar çifti kullanır; imzayı özel anahtarla atar, açık anahtarla doğrular. Saldırgan, sunucuyu HS256 kullanmaya kandırır ve herkese açık olan açık anahtarı HMAC gizli anahtarı gibi kullanarak geçerli imza üretir. Savunma: sunucu sadece beklediği algoritmayı kabul etmelidir.
Zayıf anahtar
HS256 gibi simetrik imzalarda anahtar bir paroladır. "secret", "123456" gibi zayıf anahtarlar sözlük saldırısıyla kırılır. Bu da parola kırma araçlarının konusudur. Anahtar uzun, rastgele ve gizli olmalı, koda gömülmemelidir.
JWT'de oturum sonlandırma sorunu
Klasik oturumlarda kullanıcıyı çıkış yaptırmak kolaydır: sunucudaki oturum silinir. JWT ise durumsuzdur; sunucu jetonu hatırlamaz. Bir JWT verildikten sonra, süresi dolana kadar geçerlidir. Çalınırsa geri çağırmak zordur. Çözümler:
- Kısa süre. Erişim jetonu kısa ömürlü olmalı (dakikalar), yenileme jetonu ayrı ve daha korumalı tutulmalı.
- Kara liste. İptal edilen jetonları bir listede tutmak, ama bu durumsuzluğun avantajını azaltır.
- Jeton dönüşü. Yenileme jetonu her kullanımda değişmeli, tekrar kullanım tespit edilmeli.
Güvenli JWT kontrol listesi
- İmza her istekte doğrulanır, atlanmaz.
- Sunucu kabul edeceği algoritmayı sabitler; jetonun söylediğine güvenmez.
- Gizli anahtar güçlü, rastgele ve ortam değişkeninde; kodda değil. Sızan API anahtarları yazımızdaki gibi depoya sızmamalı.
- exp (süre) ve gerekiyorsa aud, iss alanları kontrol edilir.
- Payload'a hassas veri konmaz.
- Erişim jetonu kısa, yenileme jetonu korumalı ve dönüşlü.
- Jeton mümkünse çerezde SameSite ile ya da güvenli depolamada tutulur; CSRF riski göz önüne alınır.
Sık sorulan sorular
JWT şifreli mi? Hayır. Varsayılan JWT imzalıdır ama şifreli değildir. Payload herkes tarafından okunabilir. Gizlilik gerekiyorsa JWE ya da taşıma katmanı şifrelemesi gerekir.
JWT çalınırsa ne olur? Süresi dolana kadar saldırgan onu kullanabilir. Bu yüzden kısa süre, güvenli taşıma ve yenileme jetonu dönüşü önemlidir.
localStorage'da JWT tutmak güvenli mi? localStorage XSS'e açıktır; bir XSS açığı jetonu çalabilir. SameSite çerez daha güvenli olabilir ama CSRF önlemleriyle birlikte. Doğru seçim uygulamanın tehdit modeline bağlıdır.
JWT oturum yönetimi için her zaman doğru mu? Hayır. Anlık iptal gereken, tek sunuculu ya da yüksek güvenlikli senaryolarda klasik sunucu tarafı oturum daha uygun olabilir. JWT ölçek ve durumsuzluk ister.
Kaynaklar
- OWASP, JSON Web Token for Java Cheat Sheet: https://cheatsheetseries.owasp.org
- OWASP API Security Top 10: https://owasp.org/API-Security
- RFC 7519, JSON Web Token: https://datatracker.ietf.org/doc/html/rfc7519
- PortSwigger Web Security Academy, JWT attacks: https://portswigger.net/web-security/jwt
API ve uygulamanızdaki JWT yapılandırmasını alg none, anahtar karıştırma ve imza doğrulama açısından test ettirmek için DSET ile iletişime geçin. Ankara Hacettepe Teknokent laboratuvarımızdan API güvenliği ve sızma testi hizmeti veriyoruz.
Kimliğinizi doğrulayın
Yetkilendirilmiş erişim alanı. Tüm giriş denemeleri kayıt altına alınır.