JWT Güvenliği

JWT (JSON Web Token) , taraflar arasında güvenli bir şekilde bilgi aktarımı için kullanılan, JSON tabanlı bir token standardıdır (RFC 7519). JWT'ler, kimlik doğrulama ve yetkilendirme mekanizmalarında yaygın olarak kullanılır. Ancak yanlış yapılandırma veya zafiyetler, ciddi güvenlik risklerine yol açabilir.

JWT Yapısı
JWT, üç bölümden oluşur ve nokta (.) ile ayrılır:

text
header.payload.signature
1. Header (Başlık): Token tipi ve imza algoritmasını içerir.

json
{
"alg": "HS256",
"typ": "JWT"
}
2. Payload (Gövde): Kullanıcı bilgileri ve talepleri (claims) içerir.

json
{
"sub": "1234567890",
"name": "Kullanıcı Adı",
"iat": 1516239022,
"exp": 1516242622,
"role": "user"
}
3. Signature (İmza): Header ve payload'ın birleştirilip gizli anahtarla imzalanmasıyla oluşur.

text
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
JWT Güvenlik Riskleri:
1. Zayıf İmza Algoritmaları
Risk: alg: none kullanımı veya zayıf algoritmalar.

Örnek Saldırı:

json
{
"alg": "none",
"typ": "JWT"
}
Token imzasız olarak kabul edilir ve saldırgan payload'ı değiştirebilir.

Çözüm:

alg: none kullanmayın.

Sadece güçlü algoritmalar kullanın: HS256, RS256, ES256.

HS256 kullanıyorsanız güçlü bir secret (en az 32 karakter) kullanın.

2. Zayıf veya Sızdırılmış Secret
Risk: Tahmin edilebilir veya sızdırılmış secret ile token imzalama.

Örnek Saldırı:

secret yerine password, 123456, secret gibi tahmin edilebilir değerler.

GitHub gibi platformlarda secret'ın sızdırılması.

Çözüm:

Güçlü, rastgele secret kullanın (örn: openssl rand -hex 32).

Secret'ı çevresel değişkenlerde veya vault'larda saklayın.

Düzenli olarak secret'ı döndürün (rotation).

3. Token Süresi (Expiration) Kontrolü Eksikliği
Risk: Süresi dolmayan token'lar sonsuza kadar geçerli.

Çözüm:

Token'lar için kısa ömürlü exp (expiration) claim'i kullanın.

Refresh token mekanizması ile uzun ömürlü token'ları yönetin.

Refresh token'ları veritabanında saklayın ve iptal edilebilir yapın.

json
{
"exp": 1616239022, // Expiration time
"iat": 1616235422, // Issued at
"nbf": 1616235422 // Not before
}
4. Algorithm Confusion (HS256 vs RS256)
Risk: RS256 token'ı HS256 olarak kabul etme.

Örnek Saldırı:

Uygulama RS256 kullanıyor ancak alg: HS256 gönderilirse.

Public key, HS256 imza anahtarı olarak kullanılır.

Saldırgan public key ile token imzalar.

Çözüm:

Algoritmayı doğrulayın.

alg header'ını kontrol edin ve sadece beklenen algoritmayı kabul edin.

Sabit bir algoritma kullanın (örn: sadece RS256).

python
# Python örneği
import jwt

# Sadece belirli algoritmalara izin ver
jwt.decode(token, public_key, algorithms=['RS256'])
5. Key Injection / Kid Manipülasyonu
Risk: kid (Key ID) header'ının manipüle edilmesi.

Örnek Saldırı:

json
{
"alg": "HS256",
"typ": "JWT",
"kid": "../../../../etc/passwd" // Path traversal
}
kid ile dosya okuma veya SQL injection.

kid ile özel bir anahtara yönlendirme.

Çözüm:

kid header'ını doğrulayın.

kid ile dosya sistemi erişimine izin vermeyin.

kid değerlerini sabit bir listeden kontrol edin.

6. JWT Injection (XSS ve Diğerleri)
Risk: JWT'nin payload veya header kısmına enjeksiyon.

Örnek Saldırı:

json
{
"sub": "<script>alert(1)</script>",
"name": "'; DROP TABLE users; --"
}
Çözüm:

Tüm payload alanlarını doğrulayın.

XSS koruması için çıktı kodlama yapın.

SQL injection'a karşı parametreli sorgular kullanın.

7. JWT Replay Saldırıları
Risk: Aynı token'ın tekrar tekrar kullanılması.

Çözüm:

Token'ları kısa süreli yapın (15-30 dakika).

jti (JWT ID) claim'i ile token'ı eşsiz yapın.

Token'ları veritabanında veya cache'de (Redis) saklayıp iptal edin.

json
{
"jti": "unique-token-id-123",
"exp": 1616239022
}
JWT Güvenli Uygulama Teknikleri:
1. Güvenli Token Oluşturma
python
import jwt
import datetime
import uuid

def create_jwt(user_id, user_role):
payload = {
'sub': str(user_id),
'role': user_role,
'iat': datetime.datetime.utcnow(),
'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=30),
'jti': str(uuid.uuid4()), # Benzersiz token ID
'iss': 'hedef.com',
'aud': 'api.hedef.com'
}

secret = os.environ.get('JWT_SECRET')
token = jwt.encode(payload, secret, algorithm='HS256')
return token
2. Güvenli Token Doğrulama
python
import jwt
from jwt.exceptions import InvalidTokenError

def verify_jwt(token):
try:
secret = os.environ.get('JWT_SECRET')

# Sadece belirli algoritmalara izin ver
payload = jwt.decode(
token,
secret,
algorithms=['HS256'], # Sadece HS256
issuer='hedef.com',
audience='api.hedef.com',
options={
'require': ['exp', 'iat', 'sub', 'jti']
}
)

# Token'ın iptal edilip edilmediğini kontrol et
if is_token_revoked(payload['jti']):
raise InvalidTokenError('Token iptal edildi')

return payload

except jwt.ExpiredSignatureError:
raise Exception('Token süresi doldu')
except jwt.InvalidTokenError as e:
raise Exception(f'Geçersiz token: {str(e)}')
3. Token İptal Mekanizması (Revocation)
python
import redis

def revoke_token(jti, expiry=3600):
# Redis ile token iptal
redis_client = redis.Redis()
redis_client.setex(f'revoked:{jti}', expiry, 'true')

def is_token_revoked(jti):
redis_client = redis.Redis()
return redis_client.exists(f'revoked:{jti}')
4. Refresh Token Mekanizması
python
def create_refresh_token(user_id):
payload = {
'sub': str(user_id),
'iat': datetime.datetime.utcnow(),
'exp': datetime.datetime.utcnow() + datetime.timedelta(days=7),
'jti': str(uuid.uuid4()),
'type': 'refresh'
}

secret = os.environ.get('JWT_REFRESH_SECRET')
token = jwt.encode(payload, secret, algorithm='HS256')

# Refresh token'ı veritabanında sakla
db.save_refresh_token(user_id, token)

return token

def refresh_access_token(refresh_token):
try:
secret = os.environ.get('JWT_REFRESH_SECRET')
payload = jwt.decode(refresh_token, secret, algorithms=['HS256'])

# Token tipini kontrol et
if payload.get('type') != 'refresh':
raise Exception('Geçersiz refresh token')

# Refresh token'ı veritabanında kontrol et
if not db.validate_refresh_token(payload['sub'], refresh_token):
raise Exception('Refresh token geçersiz')

# Yeni access token oluştur
new_token = create_jwt(payload['sub'], get_user_role(payload['sub']))
return new_token

except Exception as e:
raise Exception(f'Refresh token hatası: {str(e)}')
5. Güvenli Secret Yönetimi
python
# .env dosyasında saklayın
JWT_SECRET=your-super-strong-secret-key-32-characters-min
JWT_REFRESH_SECRET=another-strong-secret-key-different

# AWS Secrets Manager veya HashiCorp Vault kullanın
import boto3

def get_jwt_secret():
client = boto3.client('secretsmanager')
response = client.get_secret_value(SecretId='jwt/secret')
return response['SecretString']
6. Algoritma Zorlama
python
# Sadece belirli algoritmalara izin ver
ALLOWED_ALGORITHMS = ['HS256'] # veya ['RS256']

def decode_jwt(token):
# Header'ı decode et ve alg'yi kontrol et
import base64
import json

header = token.split('.')[0]
decoded_header = base64.urlsafe_b64decode(header + '==')
header_json = json.loads(decoded_header)

alg = header_json.get('alg')
if alg not in ALLOWED_ALGORITHMS:
raise Exception(f'İzin verilmeyen algoritma: {alg}')

# Token'ı decode et
return jwt.decode(token, get_secret(), algorithms=ALLOWED_ALGORITHMS)
7. JWT Claim Validasyonu
python
def validate_jwt_claims(payload):
required_claims = ['sub', 'iat', 'exp', 'jti']

for claim in required_claims:
if claim not in payload:
raise Exception(f'Eksik claim: {claim}')

# Subject kontrolü
if not payload['sub'].isdigit():
raise Exception('Geçersiz subject')

# Rol kontrolü
allowed_roles = ['user', 'admin', 'moderator']
if payload.get('role') not in allowed_roles:
raise Exception('Geçersiz rol')

# Issuer kontrolü
if payload.get('iss') != 'hedef.com':
raise Exception('Geçersiz issuer')

# Audience kontrolü
if payload.get('aud') != 'api.hedef.com':
raise Exception('Geçersiz audience')

return True
JWT Güvenlik Kontrol Listesi:
A. Token Oluşturma:
Güçlü algoritma kullanılıyor mu (HS256, RS256, ES256)?

Güçlü secret kullanılıyor mu (en az 32 karakter)?

exp (expiration) claim'i var mı?

iat (issued at) claim'i var mı?

jti (JWT ID) claim'i var mı?

iss (issuer) ve aud (audience) claim'leri var mı?

B. Token Doğrulama:
Algoritma doğrulanıyor mu?

exp kontrolü yapılıyor mu?

nbf (not before) kontrolü yapılıyor mu?

Token iptal kontrolü yapılıyor mu?

iss ve aud kontrolü yapılıyor mu?

C. Güvenlik Önlemleri:
Token'lar kısa süreli mi (15-30 dakika)?

Refresh token mekanizması var mı?

Secret güvenli bir yerde saklanıyor mu?

alg: none engellenmiş mi?

Key injection (kid) önlenmiş mi?

D. İzleme ve Log:
Token doğrulama hataları loglanıyor mu?

Anormal token kullanımları izleniyor mu?

Token iptal durumları loglanıyor mu?

Sık Yapılan Hatalar ve Çözümleri:
Hata Risk Çözüm
alg: none kullanımı Token doğrulama atlama alg: none engelle
Zayıf secret Brute force Güçlü secret kullan
Süresiz token Token ele geçirme Kısa süreli token
Refresh token yok Sürekli login Refresh token mekanizması
Algoritma zorlama yok Algorithm confusion Algoritma doğrulama
kid manipülasyonu Key injection kid doğrulama
İptal mekanizması yok Replay saldırısı Token iptal

🔒 Bu içeriği görmek için giriş yapın

 
Yanıt yazmak için giriş yapmalısınız
Forum özelliklerini kullanmak ve Level 2 üyelik satın almak için hesabınıza giriş yapın.
133,774Konular
3,290,554Mesajlar
324,544Kullanıcılar
infaxSon Üye
Üst Alt