without válido solutions site que pruebe por nuevamente how formulario form forgery favor enviar cross security cookies web csrf owasp

security - válido - how to exploit cross site request forgery



¿Por qué es común poner tokens de prevención de CSRF en las cookies? (3)

El uso de una cookie para proporcionar el token CSRF al cliente no permite un ataque exitoso porque el atacante no puede leer el valor de la cookie y, por lo tanto, no puede colocarlo en el lugar que la validación CSRF del lado del servidor requiere.

El atacante podrá enviar una solicitud al servidor con la cookie de token de autenticación y la cookie CSRF en los encabezados de solicitud. Pero el servidor no está buscando el token CSRF como una cookie en los encabezados de solicitud, está buscando en la carga útil de la solicitud. E incluso si el atacante sabe dónde colocar el token CSRF en la carga, tendrían que leer su valor para ponerlo allí. Pero la política de origen cruzado del navegador impide leer cualquier valor de cookie del sitio web de destino.

La misma lógica no se aplica a la cookie de token de autenticación, porque el servidor la espera en los encabezados de solicitud y el atacante no tiene que hacer nada especial para colocarla allí.

Intento comprender todo el problema con CSRF y las formas adecuadas de prevenirlo. (Recursos que he leído, entiendo y estoy de acuerdo con: Hoja de Cuestiones de Prevención de CSRF de OWASP , Preguntas sobre CSRF .)

Según entiendo, la vulnerabilidad en torno a CSRF se introduce asumiendo 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 adjuntan 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ódigo que se ejecuta 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, realizada por otros medios que no sean el manejo automático de cookies del navegador. En términos generales, entonces, la cookie de sesión autentica al usuario / navegador y el token CSRF autentica el código que se ejecuta en el navegador.

Entonces, en pocas palabras, si está utilizando una cookie de sesión para autenticar usuarios de su aplicación web, también debe agregar un token CSRF a cada respuesta y requerir un token CSRF correspondiente en cada solicitud (mutante). El token CSRF realiza una ida y vuelta desde el servidor al navegador de vuelta al servidor, lo que demuestra al servidor que la página que realiza la solicitud está aprobada por (generado por, incluso) ese servidor.

En mi pregunta, que es 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 desde el servidor al cliente como una cookie (es decir, en un encabezado Set-Cookie), y luego tener Javascript en el cliente para sacarlo 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 ej. Express , donde el token CSRF generado por el servidor se incluye en el cuerpo de respuesta a través de la expansión de la plantilla del lado del servidor, conectado directamente al código / marcado que lo proporcionará de nuevo al servidor, por ejemplo como un formulario oculto de entrada. Ese ejemplo es una forma más de web 1.0-ish de hacer las cosas, pero se generalizaría bien a un cliente más pesado de JS).

¿Por qué es tan común usar Set-Cookie como el transporte descendente para el token CSRF / por qué es esta una buena idea? Me imagino que los autores de todos estos marcos consideraron cuidadosamente sus opciones y no se equivocaron. Pero a primera vista, usar cookies para solucionar lo que esencialmente es una limitación de diseño en las cookies parece tonto. De hecho, si usaba cookies como transporte de ida y vuelta (Set-Cookies: 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) usted reintroduciría la vulnerabilidad que estamos 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 cierra la vulnerabilidad. Pero incluso el uso de Set-Cookie como transporte posterior es potencialmente engañoso y peligroso; el navegador ahora adjuntará el token CSRF a cada solicitud, incluidas las solicitudes genuinas de XSRF malintencionadas; en el mejor de los casos, hace que la solicitud sea más grande de lo que necesita ser y, en el peor de los casos, algún código de servidor bienintencionado pero equivocado podría intentar usarlo, lo que sería realmente malo. Y además, dado que el destinatario real del token CSRF es el Javascript del lado del cliente, eso significa que esta cookie no se puede proteger con solo http. Así que enviar el token CSRF en sentido descendente en un encabezado Set-Cookie parece bastante poco óptimo para mí.


Mi mejor conjetura en cuanto a la respuesta: Considere estas 3 opciones de cómo obtener el token CSRF desde el servidor al navegador.

  1. En el cuerpo de la solicitud (no en un encabezado HTTP).
  2. En un encabezado HTTP personalizado, no en Set-Cookie.
  3. Como una cookie, en un encabezado Set-Cookie.

Creo que el primer cuerpo de solicitud (aunque lo demostré con Express ) no es tan portátil para una gran variedad de situaciones; no todo el mundo genera cada respuesta HTTP de forma dinámica; donde termines necesitando poner el token en la respuesta generada puede variar ampliamente (en una entrada de forma oculta, en un fragmento de código JS o una variable accesible por otro código JS, tal vez incluso en una URL que en general parece un mal lugar poner tokens CSRF). De modo que, si bien es factible con cierta personalización, el # 1 es un lugar difícil para hacer un enfoque único para todos.

El segundo, encabezado personalizado, es atractivo pero en realidad no funciona, porque aunque JS puede obtener los encabezados de un XHR invocado, no puede obtener los encabezados de la página desde la que se cargó .

Eso deja al tercero, una cookie transportada por un encabezado Set-Cookie, como un enfoque que es fácil de usar en todas las situaciones (el servidor de cualquier persona podrá establecer encabezados de cookies por solicitud, y no importa qué tipo de los datos están en el cuerpo de la solicitud). Por lo tanto, a pesar de sus inconvenientes, fue el método más fácil de implementar ampliamente por los marcos.


Una buena razón, que usted ha tocado, es que una vez que se ha recibido la cookie CSRF, está disponible para su uso en toda la aplicación en el script del cliente para su uso tanto en formularios regulares como POST AJAX. Esto tendrá sentido en una aplicación pesada de JavaScript como la empleada por AngularJS (el uso de AngularJS no requiere que la aplicación sea de una sola página, por lo que sería útil cuando el estado deba fluir entre diferentes solicitudes de página donde el valor de CSRF normalmente no puede persistir en el navegador).

Considere los siguientes escenarios y procesos en una aplicación típica para algunos pros y contras de cada enfoque que describe. Estos se basan en el patrón de Token Synchronizer .

Solicitud de enfoque del cuerpo

  1. El usuario inicia sesión con éxito.
  2. El servidor emite una cookie de autenticación.
  3. El usuario hace clic para navegar a un formulario.
  4. Si aún no se ha generado para esta sesión, el servidor genera un token CSRF, lo almacena en la sesión del usuario y lo envía a un campo oculto.
  5. El usuario envía el formulario.
  6. El servidor comprueba el campo oculto coincide con la sesión token almacenada.

Ventajas:

  • Simple de implementar.
  • Funciona con AJAX.
  • Funciona con formularios
  • Cookie puede ser solo HTTP .

Desventajas:

  • Todos los formularios deben mostrar el campo oculto en HTML.
  • Todos los POST de AJAX también deben incluir el valor.
  • La página debe saber de antemano que requiere el token CSRF para poder incluirlo en el contenido de la página, de modo que todas las páginas deben contener el valor del token en alguna parte, lo que puede llevar mucho tiempo implementarlo en un sitio grande.

Encabezado HTTP personalizado (en sentido descendente)

  1. El usuario inicia sesión con éxito.
  2. El servidor emite una cookie de autenticación.
  3. El usuario hace clic para navegar a un formulario.
  4. La página se carga en el navegador, luego se realiza una solicitud AJAX para recuperar el token CSRF.
  5. El servidor genera el token CSRF (si no se ha generado ya para la sesión), lo almacena en la sesión del usuario y lo envía a un encabezado.
  6. El usuario envía el formulario (el token se envía a través del campo oculto).
  7. El servidor comprueba el campo oculto coincide con la sesión token almacenada.

Ventajas:

  • Funciona con AJAX.
  • La cookie puede ser solo HTTP .

Desventajas:

  • No funciona sin una solicitud AJAX para obtener el valor del encabezado.
  • Todos los formularios deben tener el valor agregado a su HTML dinámicamente.
  • Todos los POST de AJAX también deben incluir el valor.
  • La página debe realizar primero una solicitud de AJAX para obtener el token de CSRF, por lo que significará un viaje de ida y vuelta adicional cada vez.
  • Bien podría haber simplemente enviado el token a la página que guardaría la solicitud adicional.

Encabezado HTTP personalizado (ascendente)

  1. El usuario inicia sesión con éxito.
  2. El servidor emite una cookie de autenticación.
  3. El usuario hace clic para navegar a un formulario.
  4. Si aún no se ha generado para esta sesión, el servidor genera el token CSRF, lo almacena en la sesión del usuario y lo genera en el contenido de la página en algún lugar.
  5. El usuario envía el formulario a través de AJAX (el token se envía a través del encabezado).
  6. El servidor comprueba que el encabezado personalizado coincide con el token almacenado en la sesión.

Ventajas:

  • Funciona con AJAX.
  • La cookie puede ser solo HTTP .

Desventajas:

  • No funciona con formularios
  • Todos los POST de AJAX deben incluir el encabezado.

Encabezado HTTP personalizado (ascendente y descendente)

  1. El usuario inicia sesión con éxito.
  2. El servidor emite una cookie de autenticación.
  3. El usuario hace clic para navegar a un formulario.
  4. La página se carga en el navegador, luego se realiza una solicitud AJAX para recuperar el token CSRF.
  5. El servidor genera el token CSRF (si no se ha generado ya para la sesión), lo almacena en la sesión del usuario y lo envía a un encabezado.
  6. El usuario envía el formulario a través de AJAX (el token se envía a través del encabezado).
  7. El servidor comprueba que el encabezado personalizado coincide con el token almacenado en la sesión.

Ventajas:

  • Funciona con AJAX.
  • La cookie puede ser solo HTTP .

Desventajas:

  • No funciona con formularios
  • Todos los POST de AJAX también deben incluir el valor.
  • La página debe realizar primero una solicitud de AJAX para obtener el token de CRSF, por lo que significará un viaje de ida y vuelta adicional cada vez.

Set-Cookie

  1. El usuario inicia sesión con éxito.
  2. El servidor emite una cookie de autenticación.
  3. El usuario hace clic para navegar a un formulario.
  4. El servidor genera un token CSRF, lo almacena en la sesión del usuario y lo envía a una cookie.
  5. El usuario envía el formulario a través de AJAX o en formato HTML.
  6. El servidor comprueba el encabezado personalizado (o el campo de formulario oculto) coincide con el token almacenado de la sesión.
  7. La cookie está disponible en el navegador para su uso en AJAX adicional y solicitudes de formularios sin solicitudes adicionales al servidor para recuperar el token CSRF.

Ventajas:

  • Simple de implementar.
  • Funciona con AJAX.
  • Funciona con formularios
  • No requiere necesariamente una solicitud de AJAX para obtener el valor de la cookie. Cualquier solicitud HTTP puede recuperarlo y puede anexarse ​​a todas las solicitudes de formularios / AJAX a través de JavaScript.
  • Una vez que se recupera el token CSRF, ya que está almacenado en una cookie, el valor puede reutilizarse sin solicitudes adicionales.

Desventajas:

  • Todos los formularios deben tener el valor agregado a su HTML dinámicamente.
  • Todos los POST de AJAX también deben incluir el valor.
  • La cookie se enviará para cada solicitud (es decir, todas las GET para imágenes, CSS, JS, etc., que no están involucradas en el proceso de CSRF) aumentando el tamaño de la solicitud.
  • La cookie no puede ser solo HTTP .

Por lo tanto, el método de cookies es bastante dinámico y ofrece una manera fácil de recuperar el valor de la cookie (cualquier solicitud HTTP) y usarlo (JS puede agregar el valor a cualquier formulario automáticamente y puede emplearse en solicitudes AJAX como encabezado o como valor de forma). Una vez que se ha recibido el token CSRF para la sesión, no hay necesidad de regenerarlo ya que un atacante que emplea un exploit CSRF no tiene ningún método para recuperar este token. Si un usuario malintencionado intenta leer el token CSRF del usuario en cualquiera de los métodos anteriores, la política de Same Origin lo impedirá. Si un usuario malicioso intenta recuperar el lado del servidor token CSRF (por ejemplo, mediante curl ), este token no se asociará a la misma cuenta de usuario ya que la cookie de sesión de autenticación de la víctima no se incluirá en la solicitud (sería del atacante, por lo tanto no se asociará al lado del servidor con la sesión de la víctima).

Además del patrón de Token Synchronizer también está el método de prevención Double Submit Cookie CSRF, que por supuesto usa cookies para almacenar un tipo de token CSRF. Esto es más fácil de implementar ya que no requiere ningún estado del lado del servidor para el token CSRF. El token CSRF de hecho podría ser la cookie de autenticación estándar al usar este método, y este valor se envía mediante cookies como de costumbre con la solicitud, pero el valor también se repite en un campo o encabezado oculto, del cual un atacante no puede replicar como no pueden leer el valor en primer lugar. Sin embargo, se recomienda elegir otra cookie distinta de la cookie de autenticación para que la cookie de autenticación se pueda proteger marcando HttpOnly. Esta es otra razón común por la cual encontrarías la prevención de CSRF usando un método basado en cookies.