validar sistema sesiones mvc hacer con como php sql pdo hash

sistema - user login php mysql pdo



Limpieza de contraseñas de usuario (2)

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

Cuando los desarrolladores de PHP consideran descifrar las contraseñas de los usuarios por motivos 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 como escape_string() (en varias iteraciones), htmlspecialchars() , addslashes() y otras antes de codificarla y almacenarla en la base de datos.


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

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

y:

  1. Regla de normalización: El formulario de normalización Unicode C (NFC) DEBE aplicarse a todos los caracteres.

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


Nunca debe escapar, recortar ni utilizar ningún otro mecanismo de limpieza en las contraseñas que usará hash con PHP password_hash() por varias razones, la mayor de las cuales es porque hacer una limpieza adicional a la contraseña requiere un código adicional innecesario.

Argumentará (y lo ve en todas las publicaciones donde se aceptan datos de usuario para su uso en sus sistemas) que deberíamos limpiar toda la información de los usuarios y que estaría en lo cierto 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 cifrar una contraseña es el acto de 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 es necesario limpiar su entrada por razones de seguridad.

Si sigue los mantras de permitir que los usuarios usen las contraseñas / frases que desean y no limita las contraseñas , permitir cualquier longitud, cualquier número de espacios y cualquier hash de caracteres especiales 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 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 ampliar el tipo de columna para el hash almacenado, como VARCHAR(255) o TEXT .

Puede utilizar una consulta SQL completa como contraseña y se codificará, lo que hará que el motor SQL no pueda ejecutarla, por ejemplo,

SELECT * FROM `users`;

Podría reducirse a $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 &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 enviamos estos a password_hash() ? Todos se convierten en 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 de eso en la verificación de contraseña. Es un conjunto innecesario de pasos y no mejorará el hash.

¿Usa una versión de PHP inferior a 5.5? Puede usar el paquete de compatibilidad password_hash() .

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