JSON Web Token, yani JWT, üç base64 parçasından oluşan minicik bir formattır ve şu an internetin kimlik katmanının en çok kullanılan tuğlasıdır. Basit görünür, ama hikâye tam burada başlar: format basittir, kuralları ise kimsenin okumadığı uzun bir belgededir. Okunmayan belgelerin arasında dolaşan saldırgan, sizin için okuduğunuzdan çok daha fazlasını öğrenir. Bu yazı, JWT'nin en sevilen tuzaklarının turudur. Her tuzağın arkasında, "bizde olmaz" diye düşünüp uygulanmış bir örnek bulunur; turun sonunda kendi kodunuza bakışınız değişecekse, amaç gerçekleşmiştir.
alg: none — standartta açık bırakılan kapı
JWT'nin başlığı hangi algoritma ile imzalandığını yazar. Saldırgan bu başlığı değiştirip none yazar, imza kısmını boşaltır ve kütüphaneye "imzasız jeton" olarak sunar. Uygulama bu jetonu kabul ederse, kendi kendine "bu jetonun sahibi benim" diyen bir sistem kurmuş olur. Bu tuzak 2015'ten beri bilinir ve hâlâ yeniden bulunur; çünkü çoğu kütüphane, varsayılanlarda geriye dönük uyumluluk adına bu kapıyı açık bırakır. Çözüm sessiz ve nettir: doğrulama yapan taraf algoritmayı belirtmelidir.
// Kötü: hangi algoritma olursa kabul
jwt.verify(token, publicKey);
// İyi: sadece beklenen algoritma kabul edilir
jwt.verify(token, publicKey, { algorithms: ["RS256"] });
Anahtar karışıklığı ve sonsuz jeton
İkinci klasik hata, asimetrik anahtar kullanırken doğrulama tarafında imzalama anahtarını — yani gizli kalmalı anahtarı — kullanmaktır. Saldırgan jetonu kendi gizli anahtarıyla imzalar, doğrulama kodu "imza geçerli" der, oyun biter. Bu yüzden doğrulama kodu yalnızca açık anahtarla çalışmalı, imzalama ve doğrulama, farklı ortamlarda farklı anahtarlarla yapılmalıdır. Üçüncü hata süredir: exp alanı olmayan ya da "yedi gün" gibi sonsuza yakın bir süre taşıyan jetonlar. Kısa ömürlü jeton (5-15 dakika) yayımlayın, uzun ömür için yenileme jetonu kullanın.
Dördüncü hata, jetonun nerede saklandığıdır. Yerel depoda tutulan bir jeton, sayfaya sızan her betiğin eline geçer; HttpOnly ve Secure işaretli bir çerez, aynı jetonu betiğin erişemeyeceği bir yerde tutar. Saklama yeri, jetonun güvenlik modelinin parçasıdır; sonradan düşünülmeyen bir ayrıntı değil.
Payload'ı açık kutu gibi görüntüleyin
Jetonun gövdesi imzalıdır ama şifreli değildir: base64'e decode eden herkes içini okur — yeter ki tarayıcının geliştirici konsolunu ya da herhangi bir çevrimiçi çözücüyü açsın. "Yönetici" rolünü, e-posta adresini, hatta müşteri verisini payload'a koyan ekipler, verilerini yan tarafta tarayıcı kayıtlarına bırakmış olur. Kural basit: payload'a yalnızca kimlik, süre ve en gerekli iddiaları koyun; hassas veriyi asla jetona yazmayın. Jetonu bir kimlik kartı gibi düşünün: üzerinde adınız ve geçerlilik süreniz vardır, tıbbi kaydınız yok.
Bu dört tuzak, JWT'nin suçu değil; kullanıcısının harcadığı cezadır. Standartlar güvenlik sağlamaz; güvenlik, standartı doğru kullanan uygulamada yaşar. Doğrulama tarafında algoritmayı sabitleyin, imzalama ve doğrulama anahtarlarını ayırın, jeton ömrünü kısa tutun, iptal senaryonuzu tasarım aşamasında yazın. Bu dört cümle, bu yazının tüm tuzaklarını tek tek kapatır. JWT kullanan bir sistemde güvenlik denetimine girecekseniz, ilk sorunun bu dört cümle olduğundan emin olun; sorulmadıysa, denetimi siz yapın.
Okur Yorumları (0)