Pregunta Cleansing User Contrawords


¿Cómo debo escapar o limpiar las contraseñas proporcionadas por el usuario antes de hacer hash y almacenarlas en mi base de datos?

Cuando los desarrolladores de PHP consideran el uso de contraseñas de los usuarios para fines de seguridad, a menudo tienden a pensar en esas contraseñas como lo harían con cualquier otro dato proporcionado por el usuario. Este tema aparece a menudo en preguntas de PHP relacionadas con el almacenamiento de contraseñas; el desarrollador a menudo quiere limpiar la contraseña usando funciones tales como escape_string()(en varias iteraciones), htmlspecialchars(), addslashes() y otros antes de hash y almacenarlo en la base de datos.


76
2018-04-14 16:08


origen


Respuestas:


Nunca debe escapar, recortar o utilizar cualquier otro mecanismo de limpieza en las contraseñas con Hastings. password_hash() por una serie de razones, la más grande de las cuales es porque hacer una limpieza adicional de la contraseña requiere un código adicional innecesario.

Argumentará (y lo verá en cada publicación en la que los datos del usuario sean aceptados para su uso en sus sistemas) que deberíamos limpiar todos los comentarios de los usuarios y que sería correcto para cada otra información que aceptamos 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 cifrar una contraseña es hacer que la contraseña sea segura para almacenarla 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 una limpieza de su entrada por razones de seguridad

Si sigues los mantras de permitir a los usuarios usar el contraseñas / frases ellos desean y tu no limites las contraseñas, permitiendo cualquier longitud, cualquier cantidad de espacios y cualquier hash de caracteres especiales, la contraseña / frase de contraseña será segura sin importar lo que contenga la contraseña. A partir de ahora el hash más común (por defecto), 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 contraseñas codificadas 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 utilizando 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 ir más grande en el tipo de columna para el hash almacenado, como VARCHAR(255) o TEXT.

Puede utilizar una consulta SQL completa como contraseña y se correlacionará, por lo que el motor SQL no podrá realizarla, por ejemplo,

SELECT * FROM `users`;

Podría ser hasheado 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 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 &quot;dessert topping&quot; &amp; a &lt;floor wax&gt;!     " // double quotes, ampersand and braces have been changed
string(65) "I'm a &quot;dessert topping&quot; &amp; a &lt;floor wax&gt;!     " // 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 aparece cuando intentas 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

Debería ejecutar la contraseña publicada a través del método de limpieza que eligió antes de usar el resultado de la verificación de contraseña. Es un conjunto innecesario de pasos y no hará que el hash sea mejor.


¿Utiliza una versión de PHP de menos de 5.5? Puedes usar el password_hash()  paquete de compatibilidad.

Realmente no deberías usar Hashes de contraseña MD5.


88
2018-04-14 16:08



Antes de mezclar la contraseña, debe normalizarla como se describe en sección 4 de RFC 7613. En particular:

  1. Regla de mapeo adicional: cualquier instancia de espacio no ASCII DEBE ser      mapeado al espacio ASCII (U + 0020); un espacio no ASCII es cualquier Unicode      punto de código que tiene una categoría general de Unicode de "Zs" (con el      excepción de U + 0020).

y:

  1. Regla de normalización: la forma de normalización Unicode C (NFC) DEBE ser      aplicado a todos los personajes.

Esto intenta asegurar que si el usuario escribe la misma contraseña pero usando un método de entrada diferente, la contraseña aún debe ser aceptada.


31
2018-04-14 16:20