Veo que está almacenando un hash de la contraseña en la base de datos, pero para el beneficio de otros lectores, nunca almacene contraseñas en texto sin formato en la base de datos. ¡No quieres ser like Monster.com.uk!
Debería utilizar una función hash más fuerte que MD5()
. Lo ideal es que uses SHA256. Este método hash está disponible en PHP utilizando la función hash()
.
También debe aplicar un salt aleatorio a la contraseña. Almacene un valor de sal diferente para la cuenta de cada usuario. Esto ayuda a vencer los ataques de diccionario y los ataques rainbow table.
Debería aprender a utilizar la extensión mysqli en lugar de la antigua extensión mysql. Mysqli admite consultas parametrizadas, por lo que puede reducir la vulnerabilidad a algunos ataques de inyección SQL.
Aquí hay algunos ejemplos de código. Yo no lo he probado, pero debe ser bastante cerca de trabajo:
$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;
Algunas otras personas sugieren la consulta debe probar la login = ? AND password = ?
pero no me gusta hacer eso. Si hace esto, no puede saber si la búsqueda falló porque el inicio de sesión no existía o porque el usuario proporcionó una contraseña incorrecta.
Por supuesto, no debe revelar al usuario lo que causó el intento fallido de inicio de sesión, pero usted puede necesitar saber, por lo que puede registrar actividad sospechosa.
@Javier dice en su respuesta que no se debe recuperar la contraseña (o hash de la contraseña en este caso) de la base de datos. No estoy de acuerdo
Javier muestra llamando al md5()
en código PHP y enviando la cadena hash resultante a la base de datos. Pero esto no permite salarizar la contraseña fácilmente. Tienes que hacer una consulta por separado para recuperar la sal de este usuario antes de poder hacer el hash en PHP.
La alternativa es enviar la contraseña de texto claro a través de la red desde su aplicación PHP a su servidor de base de datos. Cualquier persona que intercepte su red puede ver esta contraseña. Si tiene consultas SQL registradas, cualquier persona que obtenga acceso a los registros puede ver la contraseña. Los piratas informáticos motivados incluso pueden sumergirse en el basurero para encontrar medios antiguos de copia de seguridad del sistema de archivos, ¡y pueden leer los archivos de registro de esa manera!
El riesgo menor es obtener la cadena de hash de la contraseña de la base de datos en la aplicación PHP, compararla con el hash de la entrada del usuario (también en código PHP), y luego descartar estas variables.
Nosotros aquí en stackoverflow no responder a preguntas sobre los inicios de sesión. Preferimos explicar, con gran detalle técnico, cómo desinfectar las aportaciones de los usuarios. Es mejor estar seguro que tener un sitio web funcional. – Grant
@Grant: Estás bromeando, ¿verdad? –
Tenga en cuenta que las respuestas en esta página no están actualizadas y, por lo tanto, no son seguras, consulte esta [pregunta] (http://stackoverflow.com/q/4795385/575765). – martinstoeckli