Qué es un ataque CSRF y cómo prevenirlo

CROSS-SITE REQUEST FORGERY

Un ataque CSRF consiste en forzar a un usuario a realizar peticiones HTTP, sin su consentimiento, contra una aplicación web en la que está autenticado.

Las peticiones solo pueden provocar cambios de los datos, pero no el robo de estos, ya que el atacante no puede acceder a las respuestas de las llamadas.

El usuario que recibe el ataque puede sufrir, por ejemplo, cambios en sus datos personales, en su contraseña de acceso y todo tipo de abusos, como envío de fondos entre cuentas bancarias.

Si este usuario tuviese permisos de administrador en la aplicación, toda la aplicación web podría verse comprometida.

  • Un usuario se autentica en la aplicación “mibanco.com” y el servidor le devuelve una cookie seteada bajo el dominio de “mibanco.com”, que contendrá sus credenciales de acceso y datos de sesión. Dicha cookie se guarda en el navegador del usuario.
  • Por como funcionan las cookies, siempre que desde el navegador del usuario se realice una petición contra el dominio “mibanco.com”, esta cookie será enviada de forma automática. Además, sólo las aplicaciones bajo dicho dominio pueden tener acceso de lectura a la cookie, y nadie puede modificarla, salvo el propio servidor.
  • El atacante, mediante inyección de código en la web de la aplicación o mediante phishing, consigue que el usuario envíe una petición HTTP a “mibanco.com” de forma oculta. Por ejemplo colocando un banner anunciándole que ha ganado un premio y que debe hacer click para recibirlo. Sin embargo, al pinchar podría hacer la siguiente llamada para transferir dinero al atacante:
<a href="http://mibanco.com/transferencias?cuenta=lacuentamaligna&cantidad=10000">Pincha aquí para recibir tu premio</a>
  • Al ser “mibanco.com” el destinatario, las cookies almacenadas en el navegador del usuario para dicho dominio se enviarán. Recordemos que estas cookies contenian sus credenciales de acceso.
  • El servidor de “mibanco.com” recibirá la petición junto con la cookie. Al contener las credenciales de acceso, el servidor lo tomará como una petición válida, no como un ataque, y realizará los cambios solicitados.

La prevención de los ataques CSRF se lleva a cabo incluyendo un token en la petición HTTP que debe ser validado en el servidor destino.

La forma más común de llevar esto acabo es seguir el Double Submit Cookie Pattern:

  • Trás logarse el usuario, el servidor genera el token y se lo entrega al navegador dentro de una cookie.
  • Este mismo token también debe ser incluido dentro de las peticiones HTTP que realice la aplicación desde el navegador contra el servidor.
  • En la siguiente llamada, el servidor comparará el token incluido en la llamada con el token que se encuentra en la cookie recibida. Recordemos que esta cookie se envía de forma automática al realizarse una petición al dominio bajo el que está seteada.
  • Si los dos tokens no coinciden se trata de un ataque CSRF y la petición no será procesada.
Ejemplo de flujo incluyendo el token en el post y en la cookie

Esta metodología se basa en la idea de que el atacante no puede acceder a la cookie donde se almacena este token por ningún medio, ya que sólo se tiene permiso de lectura desde el dominio desde el que ha sido entregada. Por lo tanto, no puede replicarlo en su llamada falsa y los tokens nunca podrán coincidir si se trata de un ataque CSRF.

Para mayor seguridad, en vez de incluir el mismo token por duplicado, la validación del token que va en el cuerpo de la petición se puede realizar con la clave pública de cifrado del mismo, seteándola en la cookie en lugar del token.

El token se puede entregar de las siguientes formas para ser incluido en la llamada HTTP:

  • Puede ir insertado en un campo oculto del formulario HTML renderizado por el servidor.
  • Puede ir seteado en una cookie. La aplicación web debe acceder a ella y enviarlo en las cabeceras HTTP de la llamada o en un campo oculto del formulario.

También, se podría realizar todo este proceso sin duplicidad de tokens si se almacenan los tokens o sus claves en una sesión dentro del servidor. De esta forma el token incluido en el cuerpo de la llamada recibida podría ser validado con el guardado en la sesión correspondiente.

FullStack Web Developer, JS magician

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store