Geçen hafta, uzun zamandır üzerinde çalıştığım indie oyun sunucumun ilk güvenlik audit'ini yaptırdık. Her şey yolunda gidiyor sanıyordum, ta ki güvenlikçi arkadaşımın "Kardeş, şu kullanıcı veritabanı tablosuna bir bakar mısın?" demesine kadar. Yüzümün aldığı rengi tahmin bile edemezsiniz.
Ortaya çıktı ki, kullanıcı kayıt/login sistemini yazarken, şifreleri güya güvenli bir şekilde SHA-256 ile hash'liyordum. Ama koskoca salt eklemeyi UNUTMUŞUM! Yani direkt düz metni hash'leyip veritabanına atıyordum. Kodum aşağı yukarı şöyleydi:
Python:
import hashlib
def hash_password(plain_password):
# BU KORKUNÇ, SAKIN YAPMAYIN!
return hashlib.sha256(plain_password.encode()).hexdigest()
Güvenlikçi arkadaşım ekranda bu kodu görünce, "Sen şaka mı yapıyorsun?" bakışı attı. Meğerse aynı şifreyi kullanan tüm kullanıcıların hash değerleri aynı oluyormuş. Rainbow table saldırılarına da davetiye çıkarıyormuşum. Kafayı yiyecektim, cidden.
Hemen kolları sıvadım. Her kullanıcı için benzersiz bir salt oluşturup, onu şifreyle birleştirerek hash'lemem gerekiyordu. Ayrıca bcrypt veya Argon2 gibi daha modern, yavaş hash fonksiyonlarına geçmek daha mantıklıydı. Hızlıca bcrypt kütüphanesini kurup kodu baştan yazdım:
Python:
import bcrypt
def hash_password(plain_password):
salt = bcrypt.gensalt()
hashed = bcrypt.hashpw(plain_password.encode(), salt)
return hashed.decode() # Veritabanına string olarak kaydet
Tabii eski şifreleri de yeni sisteme migrate etmek gerekti. Kullanıcı bir sonraki login olduğunda, eski hash'i kontrol edip, doğruysa yeni yöntemle yeniden hash'leyip veritabanını güncellemek için bir mekanizma yazdım. İşin en stresli kısmı buydu, kimseyi dışarıda bırakmamak lazımdı.
Güvenlik, asla "sonra hallederim" denilecek bir konu değilmiş. En temel, 101 konulardan biri olan hash'leme işlemini bile yanlış öğrenmişim veya üşenmişim. StackOverflow'da bile "salt kullanın" diye bağıran onlarca cevap varken, ben nasıl atlamışım anlamadım. Şaka gibi ama gerçek.
Siz de benzer bir acemilik yaptınız mı? Ya da şifre güvenliği için bcrypt/Argon2 dışında önerebileceğiniz, production'da test ettiğiniz başka yöntemler var mı? Konuşalım, bir daha kimse bu hataya düşmesin.