¿Es seguro o incluso común almacenar en caché los cheques de bcrypt en la memoria?

5

En una aplicación web que (como efecto secundario de la implementación del anti-patrón de contraseñas) almacena contraseñas, una recomendación es cifrarlas para almacenarlas (o hashes con sal unidireccionales costoso computacionalmente costosos). Sin embargo, hacer esto hace que el proceso del servidor pase la mayor parte del tiempo haciendo comparaciones de bcrypt con uso intensivo de la CPU, ya que el objetivo de usar bcrypt es que lleva tiempo probar una contraseña.

Mi pregunta es la siguiente: ¿es seguro almacenar en caché (en memoria) la respuesta de una comparación de bcrypt? No me preocupa pasar el tiempo una vez por proceso, pero una vez por cada solicitud única se convertirá en un cuello de botella de escalabilidad. Puntos de bonificación (?) Si puede arrojar algo de luz si es una práctica común hacerlo.

Cosas que he considerado:

  • Si solo está en la memoria, entonces es más difícil atacar
  • El almacén persistente es tan seguro como antes si está comprometido
  • Bajar el factor de carga bcrypt hace que la base de datos de contraseñas sea más vulnerable, si está comprometida
pregunta mogsie 09.01.2012 - 01:06
fuente

3 respuestas

6

El hash de contraseña se usa para el almacenamiento de contraseñas a largo plazo para tratar el caso de un acceso no deseado a la base de datos de solo lectura por parte del atacante. Esta es una amenaza realista; dicho acceso de lectura es un resultado común de los ataques exitosos de inyección SQL.

Por otro lado, un modelo común es asumir que el atacante no puede leer el contenido de RAM de un servidor activo. En ese modelo, no hay problema en almacenar la contraseña en la RAM, lo que evita tener que tocar la base de datos: la verificación de la contraseña es solo una comparación en la memoria. Los escenarios en los que un atacante puede leer la RAM sin poder tomar el control total de la máquina son bastante complicados y es poco probable que se apliquen.

El almacenamiento en caché de la salida de bcrypt no tiene mucho sentido por sí mismo, porque, para que esta información sea útil, debe estar indexada de alguna manera por la contraseña y la sal (internamente, habría un mapa "contraseña + sal" a "salida bcrypt"), por lo que el atacante que puede leer la salida bcrypt de la RAM debe poder leer la contraseña de texto simple. Aún así, en una implementación de servidor existente dada, puede ser más fácil adaptar un caché de RAM como un mapa (en el código, puede conectar eso en el "motor bcrypt" de manera transparente); como se explicó anteriormente, almacenar en caché la salida de bcrypt no es peor que almacenar las contraseñas de texto simple en la RAM, lo que generalmente está bien.

    
respondido por el Thomas Pornin 09.01.2012 - 14:48
fuente
3

Por su pregunta, parece que está enviando la contraseña al servidor en cada solicitud. Si es así, tengo que preguntar: ¿por qué demonios harías eso?

El patrón habitual es enviar la contraseña una vez en una solicitud de "inicio de sesión". Si la contraseña es correcta, el servidor envía al cliente un token de autenticación temporal generado aleatoriamente. Este token debe ser lo suficientemente largo como para resistir un ataque de fuerza bruta incluso sin técnicas de estiramiento clave, y tener un período de validez lo suficientemente corto como para comprometerlo solo presenta un riesgo limitado. (Para operaciones particularmente críticas para la seguridad, como cambiar la contraseña a largo plazo, es razonable pedirle al cliente que vuelva a enviar la contraseña original).

Por lo general, dichos tokens se almacenan en el lado del servidor en un espacio de almacenamiento de sesión a corto plazo. Supongo que podría hacer un hash con alguna función hash no extendida, solo para que un compromiso del almacenamiento de token no comprometa automáticamente todas las sesiones activas.

En el lado del cliente, es común que las aplicaciones web almacenen el token en una cookie HTTP, por lo que se envía automáticamente al servidor en cada solicitud. Tenga en cuenta que, si hace esto, debe proteger su aplicación contra los ataques de falsificación de solicitudes en sitios cruzados.

    
respondido por el Ilmari Karonen 09.01.2012 - 02:02
fuente
3
  • No, esto no es común para los hashes de contraseña
  • Es poco común porque lo que realmente desea hacer es asignar un ID de sesión temporal después de iniciar sesión en lugar de autenticar la contraseña continuamente. Esto también ayuda a prevenir ataques CSRF si se implementa de cierta manera.
  • Si arreglar tu arquitectura requiere mucho trabajo, puedes, como un espacio de almacenamiento en caché, la contraseña < - > Resultado bcrypt por un período de tiempo. Asegúrese de que esté almacenado en la memoria solamente y caduque después de un corto período de tiempo. 10 minutos es probablemente apropiado.
respondido por el Jeff Ferland 09.01.2012 - 22:57
fuente

Lea otras preguntas en las etiquetas