JWT Security Guide

JSON Web Token güvenlik açıkları ve saldırı teknikleri

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

JWT Nedir?

JSON Web Token (JWT), sistemler arasında kriptografik olarak imzalanmış JSON verilerini gönderen standart bir formattır. Genellikle kimlik doğrulama, oturum yönetimi ve erişim kontrolü mekanizmalarında kullanılır.

JWT'nin Temel Özellikleri

JWT'ler, klasik session token'larından farklı olarak tüm bilgileri client tarafında saklar. Bu, özellikle dağıtık sistemlerde ve microservice mimarilerinde popüler olmalarının ana sebebidir.

JWT Kullanım Alanları:
  • • Authentication: Kullanıcı kimlik doğrulama
  • • Authorization: Yetki kontrolü
  • • Information Exchange: Güvenli bilgi transferi
  • • Stateless Sessions: Durumsuz oturum yönetimi
  • • Single Sign-On (SSO): Tek oturum açma
JWT vs Session Tokens
Geleneksel session token'lar server tarafında saklanır ve sadece referans bilgisi içerir. JWT'ler ise tüm payload'ı kendinde taşır ve server tarafında storage gerektirmez, bu da horizontal scaling'i kolaylaştırır.

JWT'lerin güvenliği tamamen kriptografik imza üzerine kuruludur, bu da onları çeşitli saldırı vektörlerinin hedefi haline getirir.

JWT Format ve Yapısı

JWT, nokta (.) ile ayrılmış üç bölümden oluşur: Header, Payload ve Signature.

eyJraWQiOiI5MTM2ZGRiMy1jYjBhLTRhMTktYTA3ZS1lYWRmNWE0NGM4YjUiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTY0ODAzNzE2NCwibmFtZSI6IkNhcmxvcyBNb250b3lhIiwic3ViIjoiY2FybG9zIiwicm9sZSI6ImJsb2dfYXV0aG9yIiwiZW1haWwiOiJjYXJsb3NAY2FybG9zLW1vbnRveWEubmV0IiwiaWF0IjoxNTE2MjM5MDIyfQ.SYZBPIBg2CRjXAJ8vCER0LA_ENjII1JakvNQoP-Hw6GG1zfl4JyngsZReIfqRvIAEi5L4HV0q7_9qGhQZvy9ZdxEJbwTxRs_6Lb-fZTDpW6lKYNdMyjw45_alSCZ1fypsMWz_2mTpQzil0lOtps5Ei_z7mM7M8gCwe_AGpI53JxduQOaB5HkT5gVrv9cKu9CsW5MS6ZbqYXpGyOG5ehoxqm8DL5tFYaW3lB50ELxi0KsuTKEbD0t5BCl0aCR2MBJWAbN-xeLwEenaqBiwPVvKixYleeDQiBEIylFdNNIMviKRgXiYuAvMziVPbwSgkZVHeEdF5MQP1Oe2Spac-6IfA
JWT Bileşenleri
  • Header (Kırmızı): Token hakkında metadata (algoritma, tip)
  • Payload (Yeşil): Kullanıcı hakkında gerçek veriler ("claims")
  • Signature (Mavi): Header ve payload'ın kriptografik imzası
Header Decode Örneği:
{ "kid": "91366ddb3-cb0a-4a19-a07e-eadf5a44c8b5", "alg": "RS256" }
Payload Decode Örneği:
{ "iss": "portswigger", "exp": 1648037164, "name": "Carlos Montoya", "sub": "carlos", "role": "blog_author", "email": "carlos@carlos-montoya.net", "iat": 1516239022 }
JWT vs JWS vs JWE:
• JWT: Genel format spesifikasyonu
• JWS: İmzalı JWT (JSON Web Signature)
• JWE: Şifreli JWT (JSON Web Encryption)

JWT İmza Doğrulama

JWT güvenliği kriptografik imza üzerine kuruludur. Server, header ve payload'ı secret key ile imzalar, böylece verinin değiştirilmediğini doğrular.

İmza Doğrulama Süreci
  • 1. Server gelen JWT'yi alır
  • 2. Header ve payload'ı kendi secret key'i ile imzalar
  • 3. Oluşturduğu imzayı JWT'deki imza ile karşılaştırır
  • 4. Eşleşirse token geçerli, eşleşmezse geçersizdir
Secret Key'in Önemi
Secret key'in gizli kalması kritiktir. Bu key'e sahip olan herkes geçerli JWT üretebilir. Key'in tahmin edilebilir olması veya sızması, tüm sistemi tehlikeye atar.
Kritik Güvenlik Sorunu: JWT'ler client tarafında saklandığı için header ve payload kolayca okunabilir ve değiştirilebilir. Güvenlik tamamen imza doğrulamaya bağlıdır.

JWT Saldırı Türleri ve Etkisi

JWT saldırıları, kullanıcıların değiştirilmiş JWT'leri server'a göndererek kimlik doğrulama ve yetki kontrollerini bypass etmesini amaçlar.

Saldırı Etkisi
  • • Privilege Escalation: Yetki yükseltme
  • • Account Takeover: Hesap ele geçirme
  • • Authentication Bypass: Kimlik doğrulama bypass
  • • Unauthorized Access: Yetkisiz erişim
  • • Data Breach: Veri sızıntısı
Yaygın JWT Güvenlik Açığı Sebepleri:
• İmza doğrulamasının yanlış implementasyonu
• Zayıf veya tahmin edilebilir secret key'ler
• Header parametrelerinin güvenilmez şekilde kullanılması
• Algorithm confusion attacks
• Improper key management
Basit Privilege Escalation Örneği:
// Orijinal payload { "username": "carlos", "isAdmin": false } // Saldırgan tarafından değiştirilen payload { "username": "carlos", "isAdmin": true }

Eğer server imzayı düzgün doğrulamıyorsa, bu değişiklik başarılı olur.

İmza Doğrulama Bypass Saldırıları

JWT kütüphaneleri genellikle token'ları doğrulamak için bir metod ve sadece decode etmek için başka bir metod sunar.

verify() vs decode() Karışıklığı

Bazen geliştiriciler bu iki metodu karıştırır ve gelen token'ları sadece decode() metoduna geçirir. Bu durumda uygulama imzayı hiç doğrulamaz.

// Doğru kullanım jwt.verify(token, secretKey); // Yanlış kullanım (güvenlik açığı) jwt.decode(token); // İmza doğrulanmaz!
None Algorithm Saldırısı

JWT header'ındaki "alg" parametresi "none" olarak ayarlanabilir, bu "imzasız JWT" anlamına gelir:

{ "alg": "none", "typ": "JWT" }

Server'lar genellikle bu tür token'ları reddeder, ancak obfuscation teknikleri ile bypass edilebilir.

None Algorithm Bypass Teknikleri:
  • • "alg": "None" (büyük harf)
  • • "alg": "NONE" (tamamen büyük)
  • • "alg": "nOnE" (karışık)
  • • "alg": null
💡 Lab Testi: Burp Suite JWT Editor extension'ı ile "alg" parametresini "none" yapıp token'ı yeniden göndererek test edebilirsiniz.

Secret Key Brute Force Saldırıları

HS256 gibi simetrik algoritmalar arbitrary string'leri secret key olarak kullanır. Zayıf key'ler brute force ile kırılabilir.

Zayıf Secret Key Problemleri
  • • Default veya placeholder secret'ların değiştirilmemesi
  • • Online'dan kopyalanan örnek kod'lardaki hardcoded secret'lar
  • • Tahmin edilebilir pattern'lar (123456, password, secret)
  • • Çok kısa key'ler
Hashcat ile Brute Force

Hashcat kullanarak JWT secret key'lerini kırmak:

# Wordlist kullanarak brute force hashcat -a 0 -m 16500 <jwt> <wordlist> # Örnek kullanım hashcat -a 0 -m 16500 eyJhbGc... rockyou.txt # Sonuçları göstermek için hashcat -a 0 -m 16500 eyJhbGc... rockyou.txt --show
Yaygın Zayıf Secret'lar:
secret 123456 password jwt_secret your-256-bit-secret mySecretKey test admin
Brute Force Hızı
Hashcat local olarak çalıştığı için son derece hızlıdır. Büyük wordlist'ler bile dakikalar içinde taranabilir. GPU desteği ile hız daha da artar.
💡 Güçlü Secret: En az 256-bit entropysi olan, rastgele generated secret key'ler kullanın. Asla predictable string'ler kullanmayın.

JWT Header Parameter Injection

JWT header'ları (JOSE headers) sadece "alg" parametresi gerektirse de, birçok başka parametre içerebilir ve saldırganlar tarafından kötüye kullanılabilir.

Kritik Header Parametreleri:
• jwk: Embedded JSON Web Key
• jku: JSON Web Key Set URL
• kid: Key ID
• cty: Content Type
• x5c: X.509 Certificate Chain
Header Parameter Manipulation

Bu parametreler server'a hangi key'i kullanarak imzayı doğrulayacağını söyler. Saldırganlar bu parametreleri manipule ederek kendi key'lerini kullandırabilir.

Güven Problemi: Server, doğrulanmamış JWT içindeki parametrelere güvenerek hangi key'i kullanacağına karar veriyor. Bu temel bir güvenlik hatasıdır.

JWK Header Injection Saldırısı

JWS spesifikasyonu, server'ların public key'lerini doğrudan token içinde JWK formatında gömebileceklerini belirtir.

JWK (JSON Web Key)

Key'leri JSON object formatında temsil eden standart format:

{ "kid": "ed2Nf8sb-sD6ng0-scs5390g-fFD8sfxG", "typ": "JWT", "alg": "RS256", "jwk": { "kty": "RSA", "e": "AQAB", "kid": "ed2Nf8sb-sD6ng0-scs5390g-fFD8sfxG", "n": "yy1wpYmffgXBxhAUJzHHocCuJolwDqql75ZWuCQ_cb33K2vh9m" } }
Self-Signed JWK Injection

Yanlış yapılandırılmış server'lar jwk parametresindeki herhangi bir key'i kullanabilir:

  1. 1. Kendi RSA key pair'inizi generate edin
  2. 2. JWT'yi kendi private key'inizle imzalayın
  3. 3. Public key'i jwk header'ına yerleştirin
  4. 4. Token'ı server'a gönderin
Burp Suite ile JWK Injection:
  1. 1. JWT Editor Keys tab'ından yeni RSA key generate edin
  2. 2. JWT'yi Repeater'da açın
  3. 3. JSON Web Token tab'ında payload'ı değiştirin
  4. 4. Attack → Embedded JWK seçin
  5. 5. Generate ettiğiniz RSA key'i seçin
💡 Kid Parameter: JWK injection'da kid parametresinin embedded key'in kid'i ile match etmesi gerekebilir. Burp Suite extension bunu otomatik halleder.

JKU Header Injection Saldırısı

Public key'leri doğrudan gömmek yerine, bazı server'lar jku (JWK Set URL) parametresi ile key'leri external URL'den çeker.

JWK Set

Birden fazla key içeren JSON object:

{ "keys": [ { "kty": "RSA", "e": "AQAB", "kid": "75d0ef47-af89-47a9-9061-7c02a610d5ab", "n": "o-yy1wpYmffgXBxhAUJzHHocCuJolwDqql75ZWuCQ_cb33K2vh9mk6GPM9gNN4Y_qTVX67WhsN3JvaFYw-fhvsWQ" }, { "kty": "RSA", "e": "AQAB", "kid": "d8fDFo-fS9-faS14a9-ASf99sa-7c1Ad5abA", "n": "fc3f-yy1wpYmffgXBxhAUJzHql79gNNQ_cb33HocCuJolwDqmk6GPM4Y_qTVX67WhsN3JvaFYw-dfg6DH-asAScw" } ] }
JKU URL Manipulation
  1. 1. Kendi JWK Set'inizi hazırlayın
  2. 2. Bunu kendi kontrolünüzdeki server'a deploy edin
  3. 3. JWT header'ında jku'yu kendi URL'nize point edin
  4. 4. JWT'yi kendi key'inizle imzalayın
URL Parsing Bypass

Daha güvenli siteler sadece trusted domain'lerden key çeker, ancak URL parsing farklılıkları ile bypass edilebilir:

// Bypass örnekleri https://trusted-site.com.attacker.com/jwks.json https://trusted-site.com@attacker.com/jwks.json https://trusted-site.com#@attacker.com/jwks.json
Standart JWK Endpoints
JWK Set'ler genellikle /.well-known/jwks.json gibi standart endpoint'lerde expose edilir. Bu bilgi reconnaissance için kullanılabilir.

KID Parameter Path Traversal

kid (Key ID) parametresi server'a hangi key'i kullanacağını belirtir. Bu parameter genellikle database entry veya dosya yolu olarak kullanılır.

Path Traversal via KID

Kid parametresi path traversal'a açıksa, saldırganlar server'ın filesystem'indeki arbitrary dosyaları verification key olarak kullanmasını sağlayabilir:

{ "kid": "../../path/to/file", "typ": "JWT", "alg": "HS256" }
/dev/null Attack

En basit saldırı /dev/null dosyasını kullanmak:

  1. 1. kid parametresini "/dev/null" yapın
  2. 2. /dev/null boş dosya olduğu için empty string return eder
  3. 3. JWT'yi empty string ile imzalayın
  4. 4. Server da empty string ile doğrulama yapar
{ "kid": "/dev/null", "alg": "HS256", "typ": "JWT" }
Diğer Path Traversal Hedefleri:
  • • /dev/null - Empty string
  • • /proc/version - Sistem bilgisi
  • • ../../etc/passwd - Predictable content
  • • ../../../config/jwt.key - Gerçek key dosyası
SQL Injection via KID

Key'ler database'de saklanıyorsa, kid parametresi SQL injection vektörü olabilir:

{ "kid": "key1' UNION SELECT 'secret' --", "alg": "HS256", "typ": "JWT" }
💡 JWT Editor Bug: Burp Suite JWT Editor extension empty string ile signing'i desteklemez, ancak Base64-encoded null byte kullanarak bu bug bypass edilebilir.

Algorithm Confusion Attacks

Server güçlü secret'lar kullanıyor bile olsa, algorithm confusion ile hala valid JWT'ler üretilebilir. Bu saldırı geliştiricilerin beklemediği algoritmalar kullanır.

Symmetric vs Asymmetric Algorithms
  • Symmetric (HS256): Same secret key for signing and verification
  • Asymmetric (RS256): Private key for signing, public key for verification
RS256 to HS256 Confusion

En yaygın algorithm confusion saldırısı:

  1. 1. Server normalde RS256 kullanıyor (asymmetric)
  2. 2. Saldırgan alg'yi HS256 yapıyor (symmetric)
  3. 3. Server'ın public key'ini HS256 secret key olarak kullanıyor
  4. 4. JWT'yi bu "secret" ile HS256 algoritması kullanarak imzalıyor
Algorithm Confusion Örneği:
// Orijinal header (RS256) { "alg": "RS256", "typ": "JWT" } // Saldırı header (HS256) { "alg": "HS256", "typ": "JWT" }

Server'ın public key'ini secret key olarak kullanarak HS256 ile imzalama.

Public Key'in Secret Key Olarak Kullanılması

RSA public key'ler genellikle herkese açık olduğu için, bunları HS256 secret key olarak kullanmak kritik güvenlik açığı yaratır. Server unknowingly bu public key'i symmetric algorithm için kullanır.

💡 Public Key Bulma: Server'ın public key'ini /.well-known/jwks.json endpoint'inden, SSL sertifikasından veya JWK header'ından elde edebilirsiniz.

JWT Saldırılarından Korunma Yöntemleri

JWT güvenlik açıklarından korunmak için kapsamlı güvenlik önlemleri alınmalıdır.

💡 Temel Koruma Prensipleri:
  • • Güncel JWT kütüphaneleri kullanın
  • • Robust signature verification yapın
  • • Güçlü ve unique secret key'ler kullanın
  • • Header parametrelerini validate edin
  • • Algorithm whitelist uygulayın
Signature Verification Best Practices
  • • Asla decode() metodunu tek başına kullanmayın
  • • Her zaman verify() metodunu kullanın
  • • "none" algoritmasını whitelist'e almayın
  • • Algorithm confusion'a karşı koruma sağlayın
Güvenli JWT Implementation:
// Doğru - Güvenli verification const allowedAlgorithms = ['HS256', 'RS256']; const decoded = jwt.verify(token, secretKey, { algorithms: allowedAlgorithms }); // Yanlış - Güvenlik açığı const decoded = jwt.decode(token); // İmza doğrulanmaz! const decoded = jwt.verify(token, secretKey); // Algorithm belirtilmemiş
Header Parameter Security:
• jku: Strict whitelist of trusted hosts
• kid: Path traversal ve SQL injection kontrolü
• jwk: Embedded key'leri reject edin
• x5c: Certificate validation yapın
Secret Key Management
  • • Minimum 256-bit entropy ile random generation
  • • Environment variables veya secure vault'ta saklama
  • • Asla hardcode etmeyin
  • • Regular key rotation uygulayın
  • • Development/production key'lerini ayırın
Token Lifecycle Management
JWT'ler için proper lifecycle management: short expiration times, refresh token patterns, logout시 token revocation, ve aud (audience) claims kullanımı.
Additional Security Measures
  • • Always set expiration date (exp claim)
  • • Use aud (audience) claim for intended recipients
  • • Avoid sending tokens in URL parameters
  • • Implement proper logout/revocation mechanism
  • • Use HTTPS only for token transmission
  • • Monitor for suspicious JWT usage patterns
Secure JWT Configuration Örneği:
const jwtConfig = { algorithm: 'HS256', expiresIn: '15m', issuer: 'your-app.com', audience: 'your-app.com', notBefore: 0, clockTolerance: 30 }; // Token generation const token = jwt.sign(payload, secretKey, jwtConfig); // Token verification const decoded = jwt.verify(token, secretKey, { algorithms: ['HS256'], issuer: 'your-app.com', audience: 'your-app.com' });

JWT Güvenliğinin Temelleri

Güvenlik Checklist
Implementation: Always use verify(), never decode() alone
Algorithms: Strict whitelist, no "none" algorithm
Keys: Strong, random, properly managed secrets
Headers: Validate all parameters, avoid user-controlled keys
Lifecycle: Short expiration, proper revocation, HTTPS only

"Security is not a product, but a process."

Final Uyarı: JWT saldırıları gerçek dünya uygulamalarında yaygındır. Bu teknikleri sadece yetkili pentest ve bug bounty aktiviteleri için kullanın. Unauthorized testing illegal ve etik dışıdır.