¿Es una buena idea dejar que una base de datos verifique la contraseña?

1

Configuración

Un servidor que ejecuta una base de datos PostgreSQL y un Apache con varias aplicaciones php. El acceso a db es a través de la interfaz de bucle invertido. La base de datos contiene una tabla con el nombre de usuario y el hash de contraseña SHA-512-CRYPT ( $6$salt$hash ).

Solución común

Las aplicaciones leen la contraseña del usuario, la modifican y hacen una comparación de cadenas en la base de datos. Si las cadenas coinciden, el usuario se autentica.

Mi solución

La base de datos tiene una función almacenada (¿o una declaración preparada?) check_password(user, password) que las aplicaciones php consultan con SQL. Así que envían el usuario y la contraseña en claro e interpretan la respuesta de la db (por ejemplo, filas devueltas). Esto tiene la ventaja de que no tengo que asegurarme de que todas las aplicaciones admiten el mismo algoritmo hash seguro y puedo encapsular la autenticación en un solo lugar en la base de datos. Se podría hacer lo mismo para los cambios de contraseña update_password(user, old_password, new_password) .

¿Hay algún inconveniente con esta solución?

EDITAR: Se agregó una aclaración sobre el formato de contraseña almacenada.

    
pregunta problemofficer 24.04.2016 - 02:56
fuente

3 respuestas

4

La "solución común" que mencionó tiene un defecto evidente y evidente: no puede usar sal. Si su hash tiene una sal (debería), entonces necesita recuperar la sal antes de realizar la operación de hash. Y si está obteniendo la sal, debería obtener el resultado de hash al mismo tiempo. De hecho, los dos se almacenan normalmente en la misma cadena.

Idealmente, deberías obtener el hash de la base de datos y realizar el cálculo en él en tu aplicación. Tu parte acerca de no querer preocuparte por tus aplicaciones que soportan tus funciones hash es extraña. Las aplicaciones normalmente llevan, no se retrasan, las bases de datos en la adopción de tecnología.

Su solución de poner la rutina de verificación de contraseña en un procedimiento almacenado es un poco loca desde el punto de vista de la escalabilidad; El hashing de contraseñas si se hace correctamente requiere un uso intensivo del procesador y la memoria. Volcar ese tipo de carga en tu base de datos es ridículo.

Los procedimientos almacenados envían el cálculo desde el servidor web al servidor de la base de datos, al igual que las consultas complejas de SQL. Si bien eso está bien en teoría, en la práctica su base de datos tiende a ser la parte menos escalable de toda su operación. Los servidores web tienden a ser (deberían estarlo si hacen las cosas bien) completamente sin estado, por lo que ejecutar diez servidores web no requiere más trabajo que ejecutar dos. Las bases de datos no son tan simples, y ampliar su base de datos es una de las propuestas más difíciles y caras que enfrentan los sitios web más pequeños. Esto es mucho más difícil si utiliza cualquier tipo de lógica de negocios del lado de la base de datos. Si desea que la cosa sea escalable, su servidor de aplicaciones debe contener lógica y ningún estado, y su base de datos debe contener estado y no lógica.

    
respondido por el tylerl 24.04.2016 - 06:41
fuente
3

Suponiendo que su procedimiento almacenado utiliza algo como bcrypt con un salt seguro y muchas rondas, no veo ningún problema con lo que está implementando. Básicamente, trata a la base de datos como un proveedor de identidad en un sistema de identidad federada donde las aplicaciones son aplicaciones PHP.

Dicho esto, no veo ninguna razón por la que harías esto. PHP tiene funciones integradas para la administración de contraseñas. Estos están bien probados y, en caso de que se descubra un problema, se solucionarán rápidamente. Es poco probable que ese sea el caso de su procedimiento almacenado personalizado. Cuando se trata de seguridad, es (casi) siempre mejor ir por el camino más transitado. Así que apégate a los primitivos PHP y confía en que lo hicieron bien.

    
respondido por el Neil Smithline 24.04.2016 - 04:31
fuente
-1

¿El procedimiento almacenado hace salazón y varias rondas de hash seguro? Si no implementa este derecho, podría afectar el rendimiento de la base de datos y su seguridad. Hay muchas bibliotecas en casi todos los idiomas web para manejar la autenticación segura.

Utilizar un procedimiento almacenado es una buena idea al autenticar al usuario o al interactuar con cualquier tabla de cuentas. De esa manera, incluso un SQLi no podría modificar la tabla más allá de usar las funciones que creó.

EDITAR: parece que alguien hizo esto sobre el desbordamiento de pila enlace

    
respondido por el Daisetsu 24.04.2016 - 03:16
fuente

Lea otras preguntas en las etiquetas