¿evita golpear la base de datos para autenticar a un usuario en CADA solicitud en una arquitectura de aplicación web sin estado?

36

Summary

Una vez que un usuario inicia sesión en un sitio web y se verifican sus credenciales de nombre de usuario / contraseña y se establece una sesión activa, ¿es posible evitar golpear la base de datos para cada solicitud de ese usuario? ¿Cuál es el método recomendado para autenticar de forma segura las solicitudes posteriores durante la vida de la sesión, al tiempo que minimiza las consultas de base de datos y otro tráfico interno de la red?

Background

En una arquitectura de servidor de aplicaciones web sin estado, donde cada solicitud no tiene conocimiento de ninguna actividad previa del usuario, sería necesario consultar el DB en cada una de las solicitudes de ese usuario (por lo general, consultando el ID de sesión almacenado en una cookie y se transfiere en el encabezado de la solicitud). Pero, ¿qué sucede si se cifró y almacenó cierta información básica en esa cookie de sesión que tenía suficiente información para validar al usuario para solicitudes no confidenciales y no editables? Para tales solicitudes, podría, como ejemplo, cifrar y almacenar la ID de usuario y algo que identifique de forma única su máquina tanto como sea posible (usuario-agente + dirección IP) en los datos de la sesión. La clave utilizada para cifrar los datos podría cambiar diariamente, lo que dificultaría que cualquier pirata informático clonara los datos de la sesión en una máquina diferente. Cuando la sesión expire, deberá validar completamente las credenciales del usuario. El hecho es que la mayor amenaza para piratear la sesión de un usuario sería que alguien utilice la computadora de un usuario que él o ella dejaron desatendido. ¿No debería preocuparme por esto y permitir que un cierto nivel de almacenamiento en caché entre los servidores de aplicaciones web y la base de datos se encargue de acelerar el proceso de autenticación? Si bien puede parecer una optimización innecesaria, parece un candidato maduro para mejoras en la eficiencia, ya que cada solicitud requiere este proceso. Gracias por cualquier sugerencia!

    
pregunta onlinespending 22.01.2014 - 00:30
fuente

4 respuestas

41

Sí es posible, y esta técnica se usa ampliamente.

Tiene algunos inconvenientes menores en comparación con las sesiones con estado:

  1. No es compatible con el cierre de sesión fuerte. Si un usuario hace clic en cerrar sesión, la cookie se borra de su navegador. Sin embargo, si un atacante ha capturado la cookie, puede continuar usándola hasta que la cookie caduque.
  2. El uso de un secreto del lado del servidor para crear los tokens crea un único punto de falla: si se captura el secreto, un atacante puede hacerse pasar por cualquier usuario.

La decisión de usar sesiones sin estado o con estado depende de sus requisitos de rendimiento y seguridad. La banca en línea tiende a usar sesiones con estado, mientras que un blog ocupado tiende a usar sesiones sin estado.

Se requieren algunos ajustes para el esquema propuesto:

  1. El cifrado del token no lo protege de la manipulación. Desea utilizar un código de autenticación de mensaje (MAC) que protege la manipulación. Es posible que también desee utilizar el cifrado, pero eso es menos importante.
  2. Debe incluir una marca de tiempo en el token y poner un límite de tiempo en su validez. En algún lugar alrededor de 15 minutos es sensato. Normalmente, se volverá a emitir automáticamente un poco antes de que se agote el tiempo de espera y, por lo general, la nueva emisión incurrirá en un hit de la base de datos (aunque incluso eso se puede evitar)
  3. No incluya la dirección IP del usuario en el token. Aproximadamente el 3% de los usuarios cambiará legítimamente la dirección IP durante una sesión web, debido a los reinicios del módem, el cambio de los puntos de acceso de WiFi, los servidores proxy de carga equilibrada y más. Si bien puede incluir el agente de usuario en el token, no es normal hacerlo; considérelo como una técnica avanzada para usar si está seguro de que sabe lo que está haciendo.
  4. Si un atacante captura una cookie de sesión, puede hacerse pasar por ese usuario. No hay nada que puedas hacer al respecto. En su lugar, ponga todo su esfuerzo en evitar que un atacante capture la cookie en primer lugar. Use SSL, use el indicador de cookie "seguro", corrija todas las fallas de secuencias de comandos entre sitios, etc. Y pida a algunos usuarios que bloqueen su pantalla cuando su computadora está desatendida.

Espero que esto te sea útil. Si algo no está claro o necesita más información, deje un comentario y veré si puedo ayudarlo más.

    
respondido por el paj28 22.01.2014 - 11:54
fuente
16

En general, es posible "almacenar" información de estado en el cliente, incluso información confidencial como datos de autenticación; dicho almacenamiento se utiliza para ahorrar recursos en el servidor, por ejemplo, para minimizar la carga de la base de datos. Vea estas preguntas anteriores:

En pocas palabras, cada vez que desee almacenar cierta información s en el servidor, para buscarla si el mismo cliente regresa, puede enviarla como una cookie al cliente. Es posible que desee cifrado porque esa información podría ser "privada", en el sentido de que no desea mostrarla al cliente. Probablemente desee integridad porque no desea que el cliente pueda modificar los datos sin su consentimiento. Así que quieres tanto el cifrado como un MAC , o, mejor aún, uno de estos ingeniosos modos de cifrado que hacen ambos correctamente (< a href="http://en.wikipedia.org/wiki/Galois/Counter_Mode"> GCM siendo el estándar frecuentemente citado para eso).

Como de forma genérica, cuando almacena información de estado en el cliente y en el cliente, pierde un cierto control sobre el ciclo de vida de esa información. El cliente puede elegir no devolver la cookie, es decir, simular un nuevo cliente nuevo; Además, el cliente puede devolver un valor de cookie anterior. Si esto es un problema para usted depende de su situación exacta. Probablemente querrá incluir en los datos de las cookies una marca de tiempo, lo que le permitirá reconocer los valores de las cookies que son realmente demasiado antiguos.

    
respondido por el Thomas Pornin 22.01.2014 - 13:25
fuente
1

Hay algunas formas de resolver este problema (y he visto este enfoque utilizado en las API REST).

  1. Usar HTTPs para autenticar y luego usar la API sin estado.
  2. Usar un método de autenticación HTTP básico y usar un tokenID caducado en cada solicitud.

De cualquier manera, si necesita autenticación y sin estado, necesitará administrar la autenticación en su sesión de aplicación. Después de verificar las credenciales, puede realizar la consulta de la base de datos sin volver a crearla a través de un usuario confiable o similar.

Asegúrese de no permitir la conexión directa a la base de datos de ningún otro usuario que no sea el que tiene permitido hacerlo después de la verificación de credenciales.

    
respondido por el kiBytes 22.01.2014 - 11:41
fuente
0

Estoy seguro de que entiende que omitir una autenticación basada en una autenticación anterior hace de su aplicación web una aplicación de sesión. ¿No se ha autenticado un estado de sesión? Sepa que está estudiando para tener una sesión; Puede preguntarse por qué necesita una aplicación de sesión de lees. Normalmente la gente quiere aplicaciones de sesión por dos razones principales: Las solicitudes se pueden entregar a diferentes servidores sin preocuparse por la dependencia entre el cliente y cualquier miembro de una granja de servidores. Enlace de memoria cuando una gran cantidad de usuarios accede simultáneamente. Incluso en las aplicaciones de sesión, puede cumplir esos requisitos haciendo que el servidor emita un token firmado cifrado cuando la autenticación permite que otros miembros de la granja de servidores web puedan verificar que el token tenga una idea de que el usuario podría ser legítimo. La suplantación todavía es posible porque la siguiente solicitud necesita el mismo token. Puede incluir en los datos del token los encabezados http y las IP de solicitud para restringir su uso, pero los proxies intermedios aún pueden usar el token haciendo NAT y copiando los encabezados del cliente. Entonces, la única forma de hacer invulnerable a los ataques humanos es mediante la protección de la solicitud de autenticación mediante https y al permitir que el cliente le envíe con las credenciales una clave generada al azar que se utilizará para descifrar la firma de la solicitud, el cliente en cada solicitud. Encriptará algunos datos de la solicitud como una firma. Los datos cifrados pueden ser el ID de sesión y un elemento de secuencia de un generador de secuenciador preestablecido. No utilice el simple incrementado en uno debido a su comportamiento predecible. Como en cada solicitud esta firma es diferente de las firmas anteriores, puede estar seguro de que el cliente está autenticado. Si el generador del secuenciador siempre aumenta, puede almacenar en caché el último elemento utilizado para realizar una comprobación simple previa a una comprobación completa; transmitiendo a otros miembros de la granja el elemento de la secuencia utilizada dentro del ID de sesión y solo responderán si el elemento no es válido. Una secuencia de elementos no es válida si se ha utilizado en una solicitud anterior en el servidor de respuesta o si los siguientes elementos de la secuencia se agotan en la memoria caché. La prevención de la línea de memoria es una simple implementación de un servidor SQL para cada granja miembro para hacer que esta información se mantenga y tenga en la memoria solo la información más utilizada. Los dispositivos de red utilizados para la comunicación entre los miembros de la granja deben ser todos administrados por el propietario de la aplicación porque la comunicación es insegura. Con esta estructura la escalabilidad está asegurada.

    
respondido por el Oscar Gras 22.01.2014 - 19:31
fuente

Lea otras preguntas en las etiquetas