Inicio > Seguridad, Web > Cross-site Request Forgery (CSRF o XSRF)

Cross-site Request Forgery (CSRF o XSRF)

El ataque CSRF es un tipo de ataque Web que aprovecha, bien una vulnerabilidad en un sitio Web (de tipo XSS) o bien un error humano mediante ingeniería social, para invocar una acción en una tercera Web en nombre del usuario sin su consentimiento.

Es también llamado XSRF (por aquello de que la equis es comúnmente la abreviatura de cross), one-click attack o session riding. En castellano, según la entrada en Wikipedia, se puede traducir por falsificación de petición en sitios cruzados, enlace hostil, ataque de un click, cabalgamiento de sesión o ataque automático.

En este ataque el usuario de manera voluntaria o no invoca una petición HTTP GET a un tercer dominio. Esta petición realiza algún tipo de acción o proceso que beneficia al atacante, utilizando las credenciales del usuario atacado que tiene en ese momento una sesión abierta en el dominio invocado.

Por lo general, este ataque aprovecha el hecho de que la sesión autenticada y autorizada del usuario se identifica mediante una cookie que contiene el identificador de sesión del sitio. Esta cookie se envía, por el navegador, de manera automática siempre que se invoque el dominio al que pertenece. De esta manera, si la sesión no ha sido cerrada por el usuario o si no ha caducado, la petición HTTP se invoca con dicha cookie, en la sesión que identifica y con los permisos y autorizaciones que el usuario tenga conferidos.

Luego el ataque tiene que hacerse desde una sesión del navegador Web abierta por el usuario:

  • Mediante XSS (Cross-site Scripting) insertando un script que haga la petición HTTP GET al dominio a atacar cuando el usaurio acceda a un tercer dominio donde se ha insertado el script. Antes de que se sanitizase (eliminar los caracteres y cadenas de texto que facilitan que los scripts se interpreten como tales) todo el contenido que se posteaba en foros o wikis, era posible insertar el script en una entrada dentro del tema en cuestión. Cuando un usuario accedía a dicho tema, se cargaba la entrada con el script que invocaba al dominio atacado. Hoy en día los foros sanitizan de las entradas de los usuarios, aunque es posible seguir encontrando vulnerabilidades complejas que permitan el XSS.
  • Mediante la inserción, también en wikis, foros o correos, de una imagen cuya URL de referencia (atributo src) es la petición HTTP a invocar. Cuando el usuario atacado cargue la página, el navegador cargará la imagen de manera automática invocando dicha petición. No se mostrará ninguna imagen, puesto que el contenido devuelto no es una imagen, pero el daño estará hecho. Para evitar este vector de ataque, los lectores de correo no permiten la carga automática de imágenes y foros y wikis solo permiten imágenes de su dominio y siguiendo un path establecido.
  • Mediante el envío de la URL de la petición HTTP en un documento o correo y, utilizando ingeniería social, consiguiendo que el usuario lo invoque.
  • Si un troyano hiciese uso de la sesión del usuario para invocar operaciones en el sitio; no sería estrictamente CSRF, pero tendría un funcionamiento muy parecido.

En todos estos casos, el navegador invoca la URL mediante una petición HTTP y remite la cookie de usuario que está asociada a dicho dominio. Esa cookie contiene el identificador de sesión que autentica al usuario y lo autoriza para realizar dicha acción en su nombre.

Esta petición tiene que tener algún tipo de efecto lateral o secundario, tiene que hacer algún tipo de transacción (mover fondos, cambiar la contraseña del usuario, enviar un mail o postear un mensaje en su nombre…). Si no no tendría ningún efecto, ni siquiera la divulgación de información confidencial; ya que el ataque es ciego y el atacante no puede recuperar la información que ha devuelto la petición al ser invocada por el usuario desde su navegador.

En el punto 9.1.1 del RFC 2616 que define el estándar HTTP en su versión 1.1, se indica que los métodos HTTP GET y HEAD no deben efectuar acción ninguna salvo el mostrar información. Se podría pensar, que el «culpable» de este ataque es el no seguir esta recomendación y permitir efectos secundarios en las peticiones GET. Pero aunque sea adecuado y mitigue algunos vectores de ataque (atributo src en imágenes); el seguir dicha recomendación, como se indica en OWASP, no elimina la vulnerabilidad. Aún puede aprovecharse mediante la invocación de métodos POST, en formularios enviados por correo al usuario o con scripts insertados mediante XSS por ejemplo, con los mismos mecanismos y efectos que el método GET.

Tampoco sirve de nada el que la petición sea HTTPS en lugar de HTTP. El ataque es idéntico.

Es imprescindible que el usuario esté autenticado en el dominio atacado, y que su sesión esté activa, no caducada. Dicha sesión se debe identificar mediante una cookie asociada a dicho dominio, para que el navegador la envíe junto con la petición sin necesidad de que el atacante la conozca.

Con estas premisas el atacante puede efectuar con éxito el ataque sobre el usuario, y su impacto y efectos serán los que permita la petición en cuestión:

  • Mover fondos, hacer transferencias o realizar pagos
  • Postear comentarios, estado o enviar mails o mensajes en nombre del usuario
  • Cambiar la contraseña u otros parámetros (de facturación por ejemplo) del usuario en dicho dominio
  • Pujar en una subasta, apostar al juego
  • …cualquier cosa que se pueda hacer en la Web

Existen mecanismos que previenen, al menos de una manera amplia, este ataque:

  • Solicitar en cada petición un token o valor aleatorio generado e informado al navegador del usuario en el momento del login de usuario o actualizado en cada petición. El sitio desde donde se realia el ataque cruzado no podrá deducir este valor. El token puede ser un valor aleatorio o el hash de una serie de valores o nonces o el contenido de una variable enviada por el servidor y firmada por este (como hace ASP.NET con la variable ViewState). Es obligación del servidor comprobar la corrección de este token en cada petición u operación sensible. CSRFGuard es una librería de OWASP para generar e interceptar este token.
  • El envío doble de cookies es una variante del anterior, en la que el token se corresponde con el identificador de sesión en la cookie. El servidor comprueba que ambas sean iguales en cada petición. Como el sitio de donde proviene el ataque no es del mismo dominio que el atacado, el script XSS no podrá tener acceso a la cookie y deducir el valor del token.
  • Solicitar al usuario credenciales o un CAPTCHA siempre que se invoquen peticiones HTTP que realicen operaciones sensibles.
  • Limitar el tiempo de vida las sesiones lo máximo posible sin que afecte a la usabilidad de la Web.
  • Comprobar la cabecera HTTP Referer para que la petición no venga de otro dominio distinto y exigir autenticación a aquellas peticiones que no tengan la cabecera o sea de otros dominios.
  • Utilizando add-ons como RequestPolicy o CsFire que evitan la navegación cruzada entre sitios o el envío de credenciales en la navegación cruzada
  • Cambiar las URLs con efectos secundarios de manera frecuente y aleatoria permite que los atacantes solo tengan un pequeño margen de tiempo (mientras dure la URL actual) para explotar la vulnerabilidad.

Mecanismos que no funcionan, o al menos de una manera completa, son los siguientes:

  • Las HTTPOnly cookies son aquellas que el navegador almacena y gestiona como cualquier otra cookie pero que no pueden ser referenciadas por el código script de la página. Siguen autenticando de la misma manera cada petición, porque es el navegador quien envía la cookie. El atacante no requiere conocer el identificador de sesión, solo que esté activo.
  • Utilizar para acciones con efectos secundarios solo métodos POST puede evitar algún patrón, como el de las imágenes. Pero las peticiones HTTP POST también pueden generarse mediante scripting o con un formulario enviado al correo del usuario.
  • Transacciones que se realizan con más de un paso o con más de una petición HTTP, tampoco son una solución en cuanto el atacante pueda deducir el orden en que se realizan.
  • Enviar las credenciales o el identificador de sesión en los parámetros de la URL, puede evitar el CSRF pero ¡expone nuestras credenciales en proxies, en históricos de navegación, a curiosos…!

Desde el punto de vista del usuario, existen también hábitos recomendados que ayudan a evitar el ataque:

  • Cerrar siempre la sesión de usuario una vez acabemos la navegación por una Web.
  • No hacer tareas especialmente sensibles a la vez, y mucho menos, navegando por otras Webs que no sean de confianza; o al menos, con el mismo navegador.
  • Evitar en la medida de lo posible el «Recordar mi usuario» de los sitios Web sensibles.
  • Desactivar la ejecución de Javascript en sitios que no sean de confianza, para evitar el XSS que invoque métodos POST de manera automática (aún podría engañar al usuario mediante ingeniería social para que «postease» el un formulario).
  • No mostrar imágenes o pulsar links en correos y documentos provenientes de spam o cuyo origen no sea conocido o de confianza.

Un saludo,

Referencias

CSRF en Wikipedia
CSRF en OWASP
Prevención del CSRF en OWASP
RFC 2616 en IETF

Licencia Creative Commons
Esta entrada de Juan Francisco Adame Lorite está publicada bajo una licencia Creative Commons Atribución-CompartirIgual 3.0 Unported.

Categorías: Seguridad, Web Etiquetas:
  1. No hay comentarios aún.
  1. No trackbacks yet.

Comparte con nosotros tu opinión...

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

A %d blogueros les gusta esto: