CSRF Token necesario cuando se utiliza la autenticación sin estado (= sin sesión)?

¿Es necesario usar CSRF Protection cuando la aplicación se basa en la autenticación sin estado (usando algo como HMAC)?

Ejemplo:

  • Tenemos una aplicación de una sola página (de lo contrario, tenemos que agregar el token en cada enlace: ... .

  • El usuario se autentica usando POST /auth . En la autenticación exitosa, el servidor devolverá un token.

  • El token se almacenará a través de JavaScript en alguna variable dentro de la aplicación de una sola página.

  • Este token se usará para acceder a URLs restringidas como /admin .

  • El token siempre se transmitirá dentro de encabezados HTTP.

  • No hay sesión Http, y NO hay cookies.

Por lo que yo entiendo, debería (?!) no existir la posibilidad de usar ataques de sitios cruzados, porque el navegador no almacenará el token y, por lo tanto, no puede enviarlo automáticamente al servidor (eso es lo que sucedería al usar Cookies / Sesión).

¿Me estoy perdiendo de algo?

Encontré información sobre CSRF + sin utilizar cookies para la autenticación:

  1. https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/
    “dado que no confía en las cookies, no necesita protegerse contra las solicitudes cruzadas”

  2. http://angular-tips.com/blog/2014/05/json-web-tokens-introduction/
    “Si vamos por el camino de las cookies, realmente debe hacer CSRF para evitar las solicitudes cruzadas. Eso es algo que podemos olvidar al usar JWT, como verá”.
    (JWT = Json Web Token, una autenticación basada en token para aplicaciones sin estado)

  3. http://www.jamesward.com/2013/05/13/securing-single-page-apps-and-rest-services
    “La forma más fácil de realizar la autenticación sin arriesgar vulnerabilidades CSRF es simplemente evitar el uso de cookies para identificar al usuario”

  4. http://sitr.us/2011/08/26/cookies-are-bad-for-you.html
    “El mayor problema con CSRF es que las cookies no ofrecen absolutamente ninguna defensa contra este tipo de ataque. Si usa la autenticación de cookies, también debe emplear medidas adicionales para proteger contra CSRF. La precaución más básica que puede tomar es asegurarse de que su la aplicación nunca realiza ningún efecto secundario en respuesta a las solicitudes GET “.

Hay muchas más páginas, que indican que no necesita ninguna protección CSRF, si no utiliza cookies para la autenticación. Por supuesto, todavía puede usar cookies para todo lo demás, pero evite almacenar algo como session_id dentro de él.


Si necesita recordar al usuario, hay 2 opciones:

  1. localStorage : Un almacén de valores-clave en el navegador. Los datos almacenados estarán disponibles incluso después de que el usuario cierre la ventana del navegador. Los datos no son accesibles por otros sitios web, porque cada sitio tiene su propio almacenamiento.

  2. sessionStorage : También un almacén de datos en el navegador. La diferencia es: los datos se eliminan cuando el usuario cierra la ventana del navegador. Pero sigue siendo útil, si su aplicación web consta de varias páginas. Entonces puedes hacer lo siguiente:

    • El usuario inicia sesión, luego almacena el token en sessionStorage
    • El usuario hace clic en un enlace, que carga una página nueva (= un enlace real , y no contiene contenido de JavaScript, reemplace)
    • Aún puede acceder al token desde sessionStorage
    • Para cerrar la sesión, puede eliminar manualmente el token de sessionStorage o esperar a que el usuario cierre la ventana del navegador, lo que borrará todos los datos almacenados.

(para ambos, eche un vistazo aquí: http://www.w3schools.com/html/html5_webstorage.asp )


¿Hay algún estándar oficial para token auth?

JWT (Json Web Token): Creo que todavía es un borrador, pero ya lo usan muchas personas y el concepto parece simple y seguro. (IETF: http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25 )
También hay bibliotecas para muchos de los marcos disponibles. ¡Solo google para eso!

TL; DR

Un JWT, si se usa sin cookies, niega la necesidad de un token CSRF. ¡PERO! al almacenar JWT en session / localStorage, expones tu JWT y la identidad del usuario si tu sitio tiene una vulnerabilidad XSS (bastante común). Es mejor agregar una clave csrfToken al JWT y almacenar el JWT en una cookie con atributos secure y http-only .

Lee este artículo con una buena descripción para obtener más información https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage

Puede hacer que esta protección CSRF sea apátrida al incluir un reclamo xsrfToken JWT:

{ "iss": "http://galaxies.com", "exp": 1300819380, "scopes": ["explorer", "solar-harvester", "seller"], "sub": "tom@andromeda.com", "xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e" }

Por lo tanto, deberá almacenar el csrfToken en localStorage / sessionStorage, así como en el propio JWT (que se almacena en una cookie segura y de solo http). Luego, para la protección csrf, verifique que el token csrf en el JWT coincida con el encabezado csrf-token enviado.