TrendVidStream tüm kimlik doğrulama yığınını, çalınan bir jetonun yeniden kullanıldığı anda tespit edilmesini sağlayan dönen yenileme jetonu (rotating-refresh-token) sistemine taşıdı. Bu değişiklik, bir zamanlar saldırganların serbestçe dolaşmasına izin veren 30 günlük bir JWT'yi, anında oturum kapatmayı tetikleyen kısa ömürlü bir kimlik bilgisine dönüştürdü.

Tek bir ihlal bu değişikliği zorunlu kıldı: Bir ortak SDK, 30 günlük bir JWT'yi düz metin olarak önbelleğe almıştı; bir saldırgan bunu ele geçirip başka bir ülkeden tekrar kullandı ve tek çözüm, tüm kullanıcıların oturumunu kapatan imzalama anahtarını döndürmek (rotate) oldu. Bu olay, şirketin jeton güvenliğini yeniden şekillendirdi ve artık video akış hizmetine güç veriyor.

Neden eski model başarısız oldu

JWT'ler (JSON Web Tokens), bir sunucunun veritabanı sorgusu yapmadan bir isteği doğrulamasına olanak tanıyan, kendi kendine yeten, imzalı veri bloklarıdır. Bu kolaylık bir maliyeti de beraberinde getirir: Eğer bir jeton haftalarca geçerliyse, onu çalmak bir saldırgana haftalarca sürecek bir erişim sağlar. İhlal sırasında, çalınan jeton 30 günlük süresi dolana kadar geçerli kaldı çünkü onu erkenden geçersiz kılmanın bir yolu yoktu.

İmzalama anahtarını döndürmek, tüm jetonları geçersiz kılmanın tek küresel yoludur ancak bu durum her kullanıcının yeniden giriş yapmasını zorunlu kılarak hizmeti aksatır ve güveni sarsar. Hata JWT'nin kendisinde değil, tek bir uzun ömürlü kimlik bilgisine güvenilmesindeydi.

Yeni tasarımın özeti

TrendVidStream artık iki tür jeton yayınlıyor:

  • Erişim jetonları (Access tokens) – 15 dakika geçerlidir; her bir API çağrısı için gereken izinleri taşırlar.
  • Yenileme jetonları (Refresh tokens) – Kısa ömürlü bir erişim jetonunu yeni bir çiftle değiştiren, tek kullanımlık jetonlardır.

Bir istemci bir yenileme jetonu sunduğunda, sunucu:

  1. Jetonun imzasını ve iddialarını (claims) doğrular.
  2. Jetonun daha önce kullanılıp kullanılmadığını kontrol eder.
  3. Kontrol başarılıysa, yepyeni bir yenileme jetonu ve yeni bir 15 dakikalık erişim jetonu oluşturur.
  4. Eski yenileme jetonunu "kullanıldı" olarak işaretler.

Eğer 2. adım başarısız olursa —yani aynı jeton ikinci kez görünürse— sunucu bunu bir hırsızlık sinyali olarak kabul eder ve o oturuma bağlı tüm jeton "ailesini" iptal eder. Hem kurban hem de saldırgan yeniden oturum açmaya zorlanır, böylece ihlal kısa kesilir.

Jeton ailelerini takip etmek

Sistem, her jetonu izole bir kayıt olarak ele almak yerine, kullanıcı giriş yaptığında başlayan aileler halinde gruplandırır. Her döndürme işlemi, o ailenin yeni bir üyesini oluşturur. Üretimde kullanılan SQLite şeması şunları saklar:

  • family_id – Tüm oturum için sabit bir tanımlayıcı.
  • token_id – Her yenileme jetonu için benzersiz bir tanımlayıcı.
  • generation – Hata ayıklama (debugging) için yararlı bir sayaç.
  • used_at – Jetonun kullanıldığı zaman damgası.
  • revoked – Ayarlandığında tüm aileyi devre dışı bırakan bir bayrak (flag).

Bir yeniden kullanım olayı tespit edildiğinde, o family_id için revoked bayrağı ayarlanır ve böylece tehlikeye düşen oturuma ait tüm jetonlar anında geçersiz kılınır. Bu, sessiz bir ele geçirme girişimini, günlüklerde (logs) görünen yüksek sinyalli bir uyarıya dönüştürür.

Sistemi güvenilir kılan üç uygulama kuralı

  1. Önce imzayı doğrulayın Eğer sunucu imzayı doğrulamadan önce "daha önce kullanıldı mı?" kontrolünü yaparsa, bir saldırgan jeton kimliklerini tahmin edebilir ve toplu iptalleri tetikleyebilir. Önce orijinalliği doğrulamak, gereksiz hizmet reddi (DoS) saldırılarını önler.

  2. Bir tolerans süresi (grace window) tanıyın Mobil uygulamalar, bir jetonun süresi dolduğunda genellikle art arda iki yenileme isteği gönderir. Eğer sunucu çok katı olursa, ikinci istek yeniden kullanım olarak işaretlenir ve meşru bir kullanıcının oturumu kapatılır. Birkaç saniyelik bir tampon süre, "kullanılmış" bir jetonun hala yeni bir çift döndürmesine izin vererek yarış durumlarını (race conditions) yumuşatır.

  3. Tüm akışı satır kilitleme (row locking) içeren bir işlem (transaction) içine alın Atomiklik (atomicity) olmazsa, eşzamanlı iki istek de jetonu kullanan ilk kişi olduklarını düşünebilir; bu da yinelenen yenileme jetonlarının oluşturulmasına ve tek kullanımlık garanti ilkesinin bozulmasına neden olur. Jeton satırını kilitleyen bir veritabanı işlemi, yalnızca tek bir isteğin başarılı olmasını garanti eder.

Özetle: Yenileme jetonlarını tek kullanımlık hale getirerek ve yeniden kullanımı takip ederek, bir sistem çalınan her kimlik bilgisini bir alarma dönüştürebilir ve platform genelinde oturum kapatmaya zorlamadan kullanıcıları koruyabilir.