Aquí se describe un ataque de reparación de sesión de OAuth2. ¿Es posible el ataque? ¿Y estoy entendiendo correctamente cómo se puede detener?
El ataque
Mallory comienza a iniciar sesión en client.example.com
a través de un proveedor de OpenAuth2 determinado, pero justo después de que el proveedor haya enviado la respuesta de autorización ( enlace ) Mallory cierra el navegador y, por lo tanto, detiene el flujo de inicio de sesión de OAuth2. Sin embargo, antes de cerrar el navegador, recuerda el valor de Ubicación en el estado 302 Respuesta encontrada del proveedor:
HTTP/1.1 302 Found
Location: https://client.example.com/oauth-callback?code=12345&state=xyzw
Ahora Mallory configura un servidor web malvado para responder al estado 302 Encontrado con el encabezado de ubicación anterior. Envía un correo electrónico a Alice y dice: "Hola, mira esta página genial en Client.Example.Com" con un enlace a su malvado servidor web. Alice sigue el enlace y se redirige a client.example.com
con el código OAuth2 de Mallory (es decir, 12345
). client.example.com
continúa el flujo de autenticación: envía el código OAuth2 al proveedor OAuth2 y recupera un token de acceso.
El resultado es que Alice ha iniciado sesión en una cuenta que controla Mallory. Sin embargo, Alice no se da cuenta de esto y realiza una compra a través de Client.Example.Com. Client.Example.Com recuerda el número de su tarjeta de crédito, a la que Mallory tiene acceso más tarde al iniciar sesión en la cuenta y consultar el historial de la cuenta.
Evitando el ataque
OAuth2 no permite reutilizar el mismo código de autorización ( 12345
) más de una vez (consulte the RFC vinculado arriba ), pero como Mallory cerró el navegador en medio del flujo de inicio de sesión, el código de autenticación no se usa más de una vez.
En sección 10.12 en el RFC se menciona que los ataques CSRF se pueden detener a través del parámetro de estado OAuth2 ( xyzw
en este ejemplo). Sin embargo, Mallory copia el parámetro state
también, por lo que es probable que sea un estado válido, si el estado es, por ejemplo. sólo un anuncio generado aleatoriamente. Y cuando Alice sigue el enlace malvado de Mallory, client.example.com
no ha visto a nadie usar ese estado en particular anteriormente, por lo que es probable que client.exampel.com
lo acepte.
El RFC dice que el estado debería ser "por ejemplo, un hash de la cookie de sesión utilizada para autenticar al agente de usuario" . ¿Es esa la clave para prevenir este tipo de ataque? Alice tendría una cookie de sesión en client.example.com
, y el estado debería ser hashWithSha1(the-session-cookie-value)
? El state=xyzw
de Mallory sería entonces incompatible con la cookie de sesión de Alice, por lo tanto, client.example.com
se daría cuenta de que algo estaba mal con la redirección del servidor malvado de Mallory.
(¿Qué sugeriría exactamente como state
? ¿Simplemente hashWithSha1(the-session-cookie-value)
sería seguro?)