Autenticación: el nombre de usuario (correo electrónico) y la contraseña se combinan en un campo de base de datos

6

Actualmente estoy desarrollando una plataforma con un marco PHP para nuestro cliente.

El jefe del departamento de TI del cliente quiere que manejemos la autenticación con un campo de base de datos que contiene correo electrónico + contraseña + sal (hash), por lo que no hay un campo de correo electrónico de texto sin formato en esta tabla y la contraseña es más segura (su razonamiento ). El usuario debe poder iniciar sesión con su dirección de correo electrónico y contraseña. Así que la dirección de correo electrónico sirve como nombre de usuario. La idea detrás de esto es que las direcciones de correo electrónico de los usuarios son muy importantes para el negocio de nuestro cliente y el jefe de TI desea ocultar la dirección de correo electrónico en la tabla de inicio de sesión en caso de un posible ataque. (por ejemplo, un pirata informático obtiene acceso a la tabla de inicio de sesión)

Por supuesto, esto solo es posible, ya que la dirección de correo electrónico con hash para el inicio de sesión está vinculada a su dirección de correo electrónico en la tabla de perfiles. Básicamente, hay dos tablas que son necesarias para que este proceso funcione. Las tablas están en la misma base de datos, por supuesto. Una tabla de inicio de sesión con el campo de combinación de hash (correo electrónico, pw, sal) y una tabla de perfil que contiene, entre otras cosas, el correo electrónico en texto sin formato en un campo. Llamémoslo profile_email.

Recomendé encarecidamente no usar esta solución, porque nunca antes había escuchado sobre esto y ya he identificado algunos problemas posibles con esta solución.

Así que mis preguntas son: ¿Es esta una solución segura y viable? ¿Se te ocurren problemas imprevisibles? ¿Has oído hablar de soluciones similares?

    
pregunta SEoCid86 12.10.2014 - 02:21
fuente

2 respuestas

12

Por lo que puedo decir, este esquema no tiene ningún sentido. Como se ha señalado, usted aún necesita almacenar la dirección de correo electrónico de texto simple para el usuario, por lo que no existe ningún beneficio de seguridad significativo para usar el correo electrónico de texto simple y la contraseña + hash de sal frente a solo usar correo electrónico de texto plano y contraseña + hash sal.

Como estoy seguro de que ya lo ha notado, sin el correo electrónico de texto sin formato (independientemente de si está en la tabla de perfiles o en la tabla de inicio de sesión) confiar únicamente en un único valor de hash del correo electrónico + contraseña + sal no es factible (lo haría tiene que pasar por cada fila, obtener el salt, calcular el hash, ver si coincide, si no coincide, obtener el salt de la siguiente fila, calcular el hash, ver si coincide, etc, etc, etc ...) y sería un desastre de seguridad, ya que permitiría a un atacante probar los hash para todos los usuarios del sitio con un solo intento de inicio de sesión, en lugar de poder probar el hash para un usuario específico.

No veo ninguna buena razón para hacer esto. No mejora la seguridad, aumenta la complejidad y la implementación está llena de peligros. Debería cortésmente, pero presionar firmemente al cliente para que siga las mejores prácticas estándar en lugar de tratar de inventar su propio esquema descabellado.

    
respondido por el Xander 12.10.2014 - 03:09
fuente
5

¿Podría haber alguna falta de comunicación entre usted y el jefe del departamento de TI? Como Xander ya había señalado, tal esquema no funciona, e incluso agregaría que es ridículo. Para autenticar a un usuario, se debe realizar una búsqueda en la base de datos en la dirección de correo electrónico de inicio de sesión para recuperar el hash correspondiente utilizado para la comparación:

SELECT hash from Users WHERE email=?;
if($hash == hash_func($password)) then Grant access

Lo que está proponiendo ahora es hacer que la búsqueda sea más complicada agregando una operación ÚNETE para evitar una búsqueda directa en la tabla de Usuarios:

SELECT U.hash from Users U INNER JOIN Profile P WHERE P.id = U.id AND P.email=?;

La consulta de dos tablas que residen en la base de datos de same no mejora la seguridad en absoluto. También hará que el proceso de autenticación sea más engorroso y computacionalmente costoso.

Si es necesario proteger las direcciones de correo electrónico, entonces no se puede usar como parte de su esquema de autenticación. Una forma típica de superar este problema es utilizar un nombre de usuario junto con la contraseña. Esto eliminará la necesidad de realizar una búsqueda basada en la dirección de correo electrónico:

SELECT hash from Users WHERE username=?;

Luego, también te permitirá cifrar las direcciones de correo electrónico para protegerlas. Si su base de datos está alojada en un servidor diferente de su aplicación, es posible que cualquier persona que logre acceder a la base de datos no pueda recuperar las direcciones de correo electrónico.

Gracias por la aclaración. La respuesta anterior responde a su propuesta como se indica en el tercer párrafo de su pregunta. Como entiendo por su comentario a continuación, su cliente sugirió un enfoque radicalmente diferente que no requiere el uso de una segunda tabla (perfil):

SELECT id from Users WHERE hash=?;

El esquema anterior solo es viable si se asegura de que todos los hashes en la tabla sean ÚNICOS . Dado que no se está realizando ninguna búsqueda en el correo electrónico de inicio de sesión, debe abordar los siguientes problemas de seguridad:

  • cómo evitar el uso de fuerza bruta en una cuenta individual
  • probabilidad de hacer coincidir un hash a medida que aumenta la base de datos
  • la capacidad de su sitio para manejar el ataque DDOS en la página de inicio de sesión ya que el hash siempre se realiza

Por cierto, ¿su cliente acepta el riesgo de que un usuario ingrese la contraseña incorrecta e inicie sesión como otro usuario? Si es así, entonces puedes continuar con esto.

    
respondido por el Question Overflow 12.10.2014 - 06:21
fuente

Lea otras preguntas en las etiquetas