Nunca debe escapar, recortar o usar ningún otro mecanismo de limpieza en las contraseñas que usará con PHP password_hash()
por varias razones, la más importante de las cuales es porque realizar una limpieza adicional de la contraseña requiere un código adicional innecesario.
Argumentará (y lo verá en todas las publicaciones en las que se aceptan datos de usuario para su uso en sus sistemas) que deberíamos limpiar todas las entradas del usuario y que sería correcto para cualquier otra información que aceptemos de nuestros usuarios. Las contraseñas son diferentes. Las contraseñas hash no pueden ofrecer ninguna amenaza de inyección SQL porque la cadena se convierte en hash antes de almacenarla en la base de datos.
El acto de hash de una contraseña es el acto de hacer que la contraseña sea segura para almacenar en su base de datos. La función hash no le da un significado especial a ningún byte, por lo que no se requiere limpiar su entrada por razones de seguridad
Si sigue los mantras de permitir que los usuarios usen las contraseñas / frases que deseen y no limita las contraseñas , permitir cualquier longitud, cualquier cantidad de espacios y cualquier carácter especial hash hará que la contraseña / frase de contraseña sea segura sin importar lo que contenga la contraseña. A partir de ahora, el hash más común (el predeterminado), PASSWORD_BCRYPT
convierte la contraseña en una cadena de 60 caracteres de ancho que contiene una sal aleatoria junto con la información de la contraseña hash y un costo (el costo algorítmico de crear el hash):
PASSWORD_BCRYPT se usa para crear nuevos hashes de contraseña usando el algoritmo CRYPT_BLOWFISH. Esto siempre dará como resultado un hash con el formato de cripta "$ 2y $", que siempre tiene 60 caracteres de ancho.
Los requisitos de espacio para almacenar el hash están sujetos a cambios a medida que se agregan diferentes métodos de hash a la función, por lo que siempre es mejor ampliar el tipo de columna para el hash almacenado, como VARCHAR(255)
o TEXT
.
Puede usar una consulta SQL completa como contraseña y se le aplicará un hash, lo que la hará no ejecutable por el motor SQL, por ejemplo,
SELECT * FROM `users`;
Podría ser hash para $2y$10$1tOKcWUWBW5gBka04tGMO.BH7gs/qjAHZsC5wyG0zmI2C.KgaqU5G
Veamos cómo los diferentes métodos de desinfección afectan la contraseña:
La contraseña es I'm a "dessert topping" & a <floor wax>!
(hay 5 espacios al final de la contraseña que no se muestran aquí).
Cuando aplicamos los siguientes métodos de recorte, obtenemos resultados muy diferentes:
var_dump(trim($_POST['upassword']));
var_dump(htmlentities($_POST['upassword']));
var_dump(htmlspecialchars($_POST['upassword']));
var_dump(addslashes($_POST['upassword']));
var_dump(strip_tags($_POST['upassword']));
Resultados:
string(40) "I'm a "dessert topping" & a <floor wax>!" // spaces at the end are missing
string(65) "I'm a "dessert topping" & a <floor wax>! " // double quotes, ampersand and braces have been changed
string(65) "I'm a "dessert topping" & a <floor wax>! " // same here
string(48) "I\'m a \"dessert topping\" & a <floor wax>! " // escape characters have been added
string(34) "I'm a "dessert topping" & a ! " // looks like we have something missing
¿Qué sucede cuando los enviamos a password_hash()
? Todos obtienen hash, tal como lo hizo la consulta anterior. El problema surge cuando intenta verificar la contraseña. Si empleamos uno o más de estos métodos, debemos volver a emplearlos antes de compararlos con password_verify()
. Lo siguiente fallaría:
password_verify($_POST['upassword'], $hashed_password); // where $hashed_password comes from a database query
Tendría que ejecutar la contraseña publicada a través del método de limpieza que eligió antes de usar el resultado en la verificación de la contraseña. Es un conjunto de pasos innecesarios y no mejorará el hash.
¿Utiliza una versión de PHP menor a 5.5? Puede utilizar el password_hash()
paquete de compatibilidad .
Realmente no debería usar hash de contraseña MD5 .