Akışın güvenlik hedefleri
Parola sıfırlama akışı, kullanıcının mevcut parolasını bilmeden hesabına erişmesini sağlar. Bu nedenle token üretimi, saklanması, süresi, tek kullanımlı olması ve hata mesajları birlikte tasarlanmalıdır.
Önerilen akış: biçiminde yalnızca sıfırlama yetkisini temsil eden rastgele değeri içermelidir.
Token üretimi ve saklanması
PHP’de kullanılmalı; tahmin edilebilir değerler, zaman damgaları veya kullanıcı kimliği token olarak kullanılmamalıdır. Kullanıcıya gönderilen token ile veritabanında saklanan değer farklı olmalıdır. Böylece veritabanı sızsa bile henüz kullanılmamış ham token doğrudan çalıştırılamaz.
Token kaydı için şu bilgiler yeterlidir: ilgili hesap kimliği, token özeti, son geçerlilik zamanı, kullanım zamanı ve oluşturulma zamanı. Aynı hesap için yeni token oluşturulduğunda önceki aktif token’ları iptal etmek, saldırı yüzeyini azaltır. Kullanım sırasında sorgu; özete, sürenin dolmamış olmasına ve kullanılmamış olmasına göre yapılmalıdır.
Doğrulama ve parola değiştirme
Formdan gelen token’ın formatını ve makul uzunluğunu kontrol edin. Özeti sabit zamanlı karşılaştırmayla doğrulayın. Parola için kullanın; düz metin parolayı veya hızlı genel amaçlı hash algoritmalarını saklamayın.
İşlemi transaction içinde yürütmek, token’ın iki paralel istekte kullanılmasını önlemeye yardımcı olur. Token satırı koşullu biçimde tüketilmeli; ardından parola güncellenmelidir. Başarılı işlemden sonra tüm aktif oturumları, hatırlama çerezlerini ve gerekiyorsa API yenileme belirteçlerini geçersiz kılın.
Parola politikası, gereksiz karmaşıklık şartlarından çok uzunluk, parola yöneticisi desteği ve yaygın sızmış parolaların engellenmesine odaklanmalıdır. Yeni parolayı log’lamayın; token’ı da erişim, hata veya analitik kayıtlarına yazmayın.
Hata mesajları, hız sınırlama ve arayüz
Parola sıfırlama isteğinde her zaman benzer bir yanıt kullanın: “Adres kayıtlıysa sıfırlama bağlantısı gönderildi.” E-posta gönderim süresini ve HTTP yanıtını hesap varlığına göre belirgin biçimde değiştirmemeye çalışın.
IP adresi ve hesap tanımlayıcısı bazında hız sınırlama uygulayın. Aynı zamanda e-posta gönderimlerini kuyruklamak, kötüye kullanımda maliyeti düşürür. Sıfırlama sayfasında HTTPS, CSRF koruması, güvenli ve HttpOnly çerezler, uygun SameSite ayarı ve içerik güvenlik politikası kullanılmalıdır. Token’ı URL’den aldıktan sonra geçmişte veya üçüncü taraf isteklilerde sızmasını azaltmak için temiz bir URL’ye yönlendirme yapılabilir.
Test edilebilirlik kontrol listesi
Birim testleri:
Parola sıfırlama akışı, kullanıcının mevcut parolasını bilmeden hesabına erişmesini sağlar. Bu nedenle token üretimi, saklanması, süresi, tek kullanımlı olması ve hata mesajları birlikte tasarlanmalıdır.
Önerilen akış:
- Kullanıcı e-posta adresini girer.
- Sunucu her durumda aynı genel yanıtı döndürür; böylece hesabın varlığı açığa çıkmaz.
- Hesap mevcutsa kriptografik olarak güvenli, kısa ömürlü bir token üretilir.
- Token’ın kendisi yerine yalnızca özeti sunucuda saklanır.
- E-posta bağlantısı HTTPS üzerinden açılır.
- Token doğrulanır, yeni parola güvenli biçimde hash’lenir ve token hemen geçersiz kılınır.
https://example.com/reset-password?token=...Token üretimi ve saklanması
PHP’de
random_bytes()
$token = bin2hex(random_bytes(32));
$tokenHash = hash('sha256', $token);
$expiresAt = (new DateTimeImmutable('+30 minutes'))->format('Y-m-d H:i:s');
// Kullanıcıya yalnızca $token gönderilir.
// Kalıcı kayıtta $tokenHash, kullanıcı kimliği ve $expiresAt tutulur.
Token kaydı için şu bilgiler yeterlidir: ilgili hesap kimliği, token özeti, son geçerlilik zamanı, kullanım zamanı ve oluşturulma zamanı. Aynı hesap için yeni token oluşturulduğunda önceki aktif token’ları iptal etmek, saldırı yüzeyini azaltır. Kullanım sırasında sorgu; özete, sürenin dolmamış olmasına ve kullanılmamış olmasına göre yapılmalıdır.
Doğrulama ve parola değiştirme
Formdan gelen token’ın formatını ve makul uzunluğunu kontrol edin. Özeti sabit zamanlı karşılaştırmayla doğrulayın. Parola için
password_hash($password, PASSWORD_DEFAULT)İşlemi transaction içinde yürütmek, token’ın iki paralel istekte kullanılmasını önlemeye yardımcı olur. Token satırı koşullu biçimde tüketilmeli; ardından parola güncellenmelidir. Başarılı işlemden sonra tüm aktif oturumları, hatırlama çerezlerini ve gerekiyorsa API yenileme belirteçlerini geçersiz kılın.
$newHash = password_hash($newPassword, PASSWORD_DEFAULT);
// Transaction içinde:
// 1. Süresi geçmemiş ve kullanılmamış token kaydını kilitle veya koşullu güncelle.
// 2. Parola hash'ini güncelle.
// 3. Token'ı kullanılmış olarak işaretle.
// 4. Eski oturumları geçersiz kıl.
// 5. Transaction'ı tamamla.
Parola politikası, gereksiz karmaşıklık şartlarından çok uzunluk, parola yöneticisi desteği ve yaygın sızmış parolaların engellenmesine odaklanmalıdır. Yeni parolayı log’lamayın; token’ı da erişim, hata veya analitik kayıtlarına yazmayın.
Hata mesajları, hız sınırlama ve arayüz
Parola sıfırlama isteğinde her zaman benzer bir yanıt kullanın: “Adres kayıtlıysa sıfırlama bağlantısı gönderildi.” E-posta gönderim süresini ve HTTP yanıtını hesap varlığına göre belirgin biçimde değiştirmemeye çalışın.
IP adresi ve hesap tanımlayıcısı bazında hız sınırlama uygulayın. Aynı zamanda e-posta gönderimlerini kuyruklamak, kötüye kullanımda maliyeti düşürür. Sıfırlama sayfasında HTTPS, CSRF koruması, güvenli ve HttpOnly çerezler, uygun SameSite ayarı ve içerik güvenlik politikası kullanılmalıdır. Token’ı URL’den aldıktan sonra geçmişte veya üçüncü taraf isteklilerde sızmasını azaltmak için temiz bir URL’ye yönlendirme yapılabilir.
Test edilebilirlik kontrol listesi
Birim testleri:
- Token’ın yeterli uzunlukta ve her üretimde farklı olduğu doğrulanır.
- Süresi dolmuş, kullanılmış, değiştirilmiş veya bulunamayan token reddedilir.
- Yeni parola doğru algoritmayla hash’lenir ve eski parola artık çalışmaz.
- Token’ın ham hali log, hata mesajı veya kalıcı kayıtta bulunmaz.
- Var olan ve olmayan e-posta adresleri aynı genel yanıtı üretir.
- Geçerli bağlantı yalnızca bir kez kullanılabilir.
- İkinci paralel isteklerden yalnızca biri başarılı olur.
- Başarılı sıfırlamadan sonra eski oturum ve hatırlama çerezleri geçersizdir.
- Hız sınırı aşıldığında e-posta gönderimi durur ve güvenli hata yanıtı döner.