Estoy tratando de entender todo el problema con CSRF y las formas adecuadas de prevenirlo. (Recursos que he leído, entiendo y estoy de acuerdo con: OWASP CSRF Prevention CHeat Sheet , Preguntas sobre CSRF ).
Según tengo entendido, la vulnerabilidad en torno a CSRF se introduce por el supuesto de que (desde el punto de vista del servidor web) una cookie de sesión válida en una solicitud HTTP entrante refleja los deseos de un usuario autenticado. Pero todas las cookies para el dominio de origen se unen mágicamente a la solicitud del navegador, por lo que realmente todo el servidor puede inferir de la presencia de una cookie de sesión válida en una solicitud que la solicitud proviene de un navegador que tiene una sesión autenticada; no puede asumir nada más sobre el códigoejecutándose en ese navegador, o si realmente refleja los deseos del usuario. La forma de evitar esto es incluir información de autenticación adicional (el "token CSRF") en la solicitud, transportada por algún otro medio que no sea el manejo automático de cookies del navegador. En términos generales, la cookie de sesión autentica al usuario / navegador y el token CSRF autentica el código que se ejecuta en el navegador.
En pocas palabras, si está utilizando una cookie de sesión para autenticar a los usuarios de su aplicación web, también debe agregar un token CSRF a cada respuesta y requerir un token CSRF coincidente en cada solicitud (mutante). El token CSRF luego realiza un viaje de ida y vuelta desde el servidor al navegador de regreso al servidor, demostrando al servidor que la página que realiza la solicitud es aprobada por (generado por, incluso) ese servidor.
En cuanto a mi pregunta, que trata sobre el método de transporte específico utilizado para ese token CSRF en ese viaje de ida y vuelta.
Parece común (por ejemplo, en AngularJS , Django , Rails ) enviar el token CSRF del servidor al cliente como una cookie (es decir, en un encabezado Set-Cookie), y luego tener Javascript en el cliente para eliminarlo de la cookie y adjuntarlo como un encabezado XSRF-TOKEN separado para enviar de vuelta al servidor.
(Un método alternativo es el recomendado por , por ejemplo , Express , donde el token CSRF generado por el servidor se incluye en el cuerpo de la respuesta a través de la expansión de la plantilla del lado del servidor, adjunta directamente al código / marcado que lo devolverá al servidor, por ejemplo como una entrada de formulario oculta. Ese ejemplo es una forma más web 1.0-ish de hacer las cosas, pero generalizaría bien a un cliente más pesado de JS).
¿Por qué es tan común usar Set-Cookie como transporte descendente para el token CSRF / por qué es una buena idea? Me imagino que los autores de todos estos marcos consideraron sus opciones cuidadosamente y no se equivocaron. Pero a primera vista, el uso de cookies para evitar lo que es esencialmente una limitación de diseño de las cookies parece una tontería. De hecho, si utilizó cookies como transporte de ida y vuelta (Set-Cookie: encabezado aguas abajo para que el servidor le diga al navegador el token CSRF, y Cookie: encabezado aguas arriba para que el navegador lo devuelva al servidor) volvería a introducir la vulnerabilidad están tratando de arreglarlo
Me doy cuenta de que los marcos anteriores no usan cookies para todo el viaje de ida y vuelta para el token CSRF; usan Set-Cookie en sentido descendente, luego algo más (por ejemplo, un encabezado X-CSRF-Token) en sentido ascendente, y esto elimina la vulnerabilidad. Pero incluso el uso de Set-Cookie como transporte descendente es potencialmente engañoso y peligroso; el navegador ahora adjuntará el token CSRF a cada solicitud, incluidas las solicitudes XSRF maliciosas genuinas; en el mejor de los casos, eso hace que la solicitud sea más grande de lo que debe ser y, en el peor de los casos, un código de servidor bien intencionado pero equivocado podría intentar usarlo, lo que sería realmente malo. Y además, dado que el destinatario real del token CSRF es Javascript del lado del cliente, eso significa que esta cookie no se puede proteger con http-only.