Vidím, že v databázi ukládáte hash hesla, ale ve prospěch ostatních čtenářů nikdy ukládat hesla v databázi jako prostý text. Nechcete být jako Monster.com.uk !
Měli byste použít silnější hašovací funkci než MD5()
. V ideálním případě byste měli používat SHA256. Tato metoda hash je dostupná v PHP pomocí hash()
funkce.
Měli byste také použít náhodnou sůl k heslu. Pro každý uživatelský účet uložte jinou hodnotu soli. To pomáhá porazit slovníkové útoky a duhovou tabulku útoky.
Měli byste se naučit používat mysqli rozšíření místo starého rozšíření mysql. Mysqli podporuje parametrizované dotazy, takže můžete snížit zranitelnost vůči některým útokům SQL injection.
Zde je několik příkladů kódu. Netestoval jsem to, ale mělo by to být docela blízko k provozu:
$input_login = $_POST['login'];
$input_password = $_POST['password'];
$stmt = $mysqli->prepare("SELECT password, salt FROM customer WHERE login = ?");
$stmt->bind_param("s", $input_login);
$stmt->execute();
$stmt->bind_result($password_hash, $salt);
while ($stmt->fetch()) {
$input_password_hash = hash('sha256', $input_password . $salt);
if ($input_password_hash == $password_hash) {
return true;
}
// You may want to log failed password attempts here,
// for security auditing or to lock an account with
// too many attempts within a short time.
}
$stmt->close();
// No rows matched $input_login, or else password did not match
return false;
Někteří další lidé navrhují, aby byl dotaz testován na login = ? AND password = ?
ale nerada to dělám. Pokud to uděláte, nemůžete vědět, zda se vyhledávání nezdařilo, protože přihlášení neexistovalo nebo protože uživatel zadal špatné heslo.
Samozřejmě byste neměli prozradit uživateli, kdo způsobil neúspěšný pokus o přihlášení, ale vám možná budete potřebovat vědět, abyste mohli zaznamenat podezřelou aktivitu.
@Javier ve své odpovědi říká, že byste neměli získávat heslo (nebo v tomto případě hash hesla) z databáze. Nesouhlasím.
Javier ukazuje volání md5()
v PHP kódu a odeslání výsledného hash řetězce do databáze. To však nepodporuje snadné vysolování hesla. Než budete moci provést hash v PHP, musíte provést samostatný dotaz k načtení soli tohoto uživatele.
Alternativou je odeslání prostého textu heslo přes síť z vaší aplikace PHP na váš databázový server. Toto heslo může vidět kdokoli, kdo odposlouchává vaši síť. Pokud jsou protokolovány dotazy SQL, každý, kdo získá přístup k protokolům, uvidí heslo. Motivovaní hackeři mohou dokonce hledat staré záložní médium souborového systému a mohou tak číst soubory protokolu!
Menším rizikem je načíst řetězec hash hesla z databáze do aplikace PHP, porovnat jej s hodnotou hash zadané uživatelem (také v kódu PHP) a pak tyto proměnné zahodit.