Desmitificando la autenticación web (cookies de sesión sin estado)

41

Actualmente estoy investigando los protocolos de autenticación de usuarios para un sitio web que estoy desarrollando. Me gustaría crear una cookie de autenticación para que los usuarios puedan permanecer conectados entre páginas.

Aquí está mi primera fiesta:

cookie = user_id|expiry_date|HMAC(user_id|expiry_date, k)

Donde k es HMAC(user_id|expiry_date, sk) y sk es una clave de 256 bits que solo conoce el servidor. HMAC es un hash SHA-256. Tenga en cuenta que '|' Es un separador, no solo de concatenación.

Esto se parece a esto en PHP (Nota, esta pregunta es independiente del lenguaje, PHP es solo un ejemplo):

$key = hash_hmac('sha256', $user_id . '|' . $expiry_time, SECRET_KEY);
$digest = hash_hmac('sha256', $user_id . '|' . $expiry_time, $key);
$cookie = $user_id . '|' . $expiry_time . '|' . $digest;

Puedo ver que es vulnerable a los ataques de reproducción como se indica en A Secure Cookie Protocol , pero debería ser resistente a los ataques de volumen y al empalme criptográfico.

LA PREGUNTA: ¿Estoy en la línea correcta aquí, o hay una vulnerabilidad masiva que me he perdido? ¿Hay alguna forma de defenderse contra los ataques de reproducción que funcionan con direcciones IP asignadas dinámicamente y que no usan sesiones? No quiero almacenar nada en el lado del servidor para que funcione.

Además, no estoy planeando o haciendo rodar la mía. Estoy pidiendo esto para juzgar mejor qué solución debo elegir. Así que no hay respuestas de "solo usa la solución X" sin algún tipo de explicación.

NOTAS

El material más reciente que he leído:
Qué hacer y qué no hacer con la autenticación del cliente en la Web alias fu et al.
( enlace )

Un protocolo de cookie seguro aka Liu et al.
( enlace )
que se expande en el método anterior

Cookies de sesión sin estado reforzadas
( enlace )

que también se expande en el método anterior.

Como el tema es extremadamente complicado, solo busco respuestas de expertos en seguridad con experiencia en el mundo real para crear y romper esquemas de autenticación.

    
pregunta Joony 11.02.2013 - 15:27
fuente

4 respuestas

34

Los "ataques de reproducción" no se aplican realmente a las cookies, porque una cookie es por definición algo que debe reproducirse: el navegador del usuario envía el mismo valor de cookie, y así es como su servidor sabe que es el mismo usuario.

Lo que quiere evitar es que alguien espíe en la línea, observe el valor de la cookie y luego envíe la misma cookie en sus propias conexiones. La única solución práctica conocida para esto es ejecutar todo el protocolo dentro de un túnel que garantice la confidencialidad y la integridad de los datos en tránsito, y eso se conoce como "SSL" (también conocido como HTTPS ).

Luego, hay dos formas de generar y verificar los valores de las cookies en el servidor:

  • Puede generar un valor aleatorio de tamaño suficiente (es decir, 16 bytes o menos), de modo que sería muy improbable que un atacante adivine el valor por pura suerte. El servidor recuerda a cada usuario su "token de sesión" actual, como una columna adicional en la base de datos de "usuarios".

  • Produces el token como un valor imperdonable calculado de manera determinista a partir del identificador de usuario. Eso es lo que haces, y ese es un concepto razonable. Básicamente, en lugar de almacenar un estado adicional en el servidor, lo descarga en el cliente y usa un MAC con un clave del lado del servidor para que los clientes no puedan falsificar valores de cookie "válidos".

Su código describe dos llamadas HMAC anidadas, lo cual es extraño e injustificado. Una llamada es suficiente. La construcción genérica es que una cookie contiene un valor v y un MAC m tal que v codifica el estado que desea almacenar en el cliente, y m se calcula sobre v . El estado que desea almacenar, en su caso, es: "este cliente tiene el ID de usuario i e inició sesión en el momento t ". Puede utilizar la codificación que desee, siempre que pueda decodificarla sin ambigüedades.

Para resumir: producir valores de cookie con un MAC es una forma válida de hacer la administración de la sesión, y HMAC / SHA-256 es bueno para eso. Pero debe pensarlo como una optimización : almacena valores en el cliente para evitar almacenarlos en el servidor. Esto tiene la desafortunada consecuencia de que el cliente puede olvidar los datos que están fuera de su control (el cliente puede destruir la cookie) o puede hacer modificaciones temporales (el cliente puede cambiar el valor almacenado en su navegador a un valor de cookie más antiguo, un problema que es mitigado al incluir fechas en las cookies, bajo el control del MAC).

Si puede mantener el lado del servidor de estado y simplemente usar valores de cookies aleatorios, hágalo: es más simple y le da más control al servidor.

    
respondido por el Thomas Pornin 11.02.2013 - 16:54
fuente
13

El primer paso para proteger cualquier aplicación web es usar SSL. Eso mantiene la confidencialidad de su cookie, evita los ataques de reproducción, asegura que el usuario está hablando con el servidor correcto, evita MitM, evita que los atacantes cambien los datos en la red ...

Luego, establezca el indicador secure en la cookie, para que solo se envíe por SSL. Al establecer el indicador http-only , para evitar que javascript lo lea, tampoco está mal.

Por último, con respecto a su esquema de cookies:

  • La HMAC anidada no te gana nada. Solo ve con user_id|expiry_date|HMAC(user_id|expiry_date, SECRET_KEY)
  • Cambia SECRET_KEY regularmente
  • El user_id nunca debe cambiar. es decir, utilice el user_id numérico, no el nombre de usuario o el correo electrónico
  • Ni user_id ni expiry_date deberían contener un | para garantizar una separación de dominio limpia
  • Si está paranoico, use un servidor de inicio de sesión especializado, que firme la cookie en lugar de enviarla por MAC. Por lo tanto, el servidor de inicio de sesión es el único que tiene la clave necesaria para crear cookies, los servidores web normales solo pueden validarlo. = > reduce la superficie de ataque
  • El servidor puede crear cookies válidas para cualquier usuario. Eso podría ser indeseable.
respondido por el CodesInChaos 11.02.2013 - 15:49
fuente
8

Primero y más importante:

No inventes tus propios protocolos de seguridad. Es muy probable que lo hagas mal.

Ahora que está fuera del camino, veamos esto. Si alguna vez puedo obtener HMAC(userid|expiry_date, k) , sin iniciar sesión o haberme autenticado como ese usuario, he roto la seguridad de este sistema. Esto se extiende a todo tipo de problemas, como la fijación de sesión o los ataques de secuestro de sesión (a menudo causados por no, o incorrectamente, el uso de SSL / TLS).

Cuando está verificando la cookie de sesión, ¿está perdiendo información de los canales laterales de temporización? ¿Definitivamente estás usando HMAC correctamente? Usted dijo que su HMAC es SHA-256, ¿realmente quiere decir HMAC-SHA-256? ¿Por qué pasar por un procedimiento HMAC complicado, cuando podría generar una cadena aleatoria y asociarla con un usuario en el servidor (por ejemplo, en una base de datos)? ¿Por qué no usar simplemente user_id|expiry_date|HMAC-SHA-256(user_id|expiry_date, sk) (donde | es concatenación, no el carácter de canalización literal)?

En cuanto a la defensa contra ataques de repetición en un entorno basado en web, consulte CSRFGuard project OaAS>. No podrá integrarlo directamente, pero puede haber un equivalente de PHP en algún lugar. Sin embargo, todo es discutible si su sitio es vulnerable a los ataques XSS.

La seguridad se debe entregar a un marco respetado y probado en el campo de batalla, no debe hacerse ad hoc

Editar, una breve palabra sobre los ataques de fijación de sesión:

Supuse que si no estás administrando seguridad a un marco bien probado, es probablemente vulnerable. Básicamente, tendrá que verificar que está emitiendo una clave de sesión distinta cuando el usuario se autentica (es decir, diferente a la que el usuario inició). Con la estrategia anterior, user_id|expiry_date|HMAC(user_id|expiry_date, k) no cambiaría cuando el usuario se autentique, dejándolos vulnerables a un ataque de fijación de sesión.

    
respondido por el Tinned_Tuna 11.02.2013 - 15:53
fuente
3
  

Como el tema es extremadamente complicado, solo busco respuestas de expertos en seguridad con experiencia en el mundo real para crear y romper esquemas de autenticación.

Tienes razón en que el tema es extremadamente complicado.

Vaya con las funciones de sesión proporcionadas por su marco y no intente rodar las suyas. Si está utilizando PHP simple en lugar de un marco ... se estremece .

    
respondido por el Ayrx 11.02.2013 - 15:38
fuente

Lea otras preguntas en las etiquetas