CSRF ( falsificación de solicitud en sitios cruzados en inglés - "falsificación de solicitud en sitios cruzados", también conocida como XSRF) es un tipo de ataque a los visitantes del sitio web que utiliza las deficiencias del protocolo HTTP . Si una víctima visita un sitio creado por un atacante, se envía en secreto una solicitud en nombre de la víctima a otro servidor (por ejemplo, a un servidor de sistema de pago) que realiza algún tipo de operación maliciosa (por ejemplo, transferir dinero a la cuenta de un atacante). cuenta). Para llevar a cabo este ataque, la víctima debe estar autenticada en el servidor al que se envía la solicitud, y esta solicitud no debe requerir ninguna confirmación por parte del usuario., que no puede ser ignorado o falsificado por un script atacante .
Este tipo de ataque, contrariamente a la idea errónea popular, apareció hace bastante tiempo: las primeras consideraciones teóricas aparecieron en 1988 [1] y las primeras vulnerabilidades se descubrieron en 2000 . Y el término mismo fue introducido por Peter Watkins en 2001 .
El uso principal de CSRF es forzar la realización de cualquier acción en un sitio vulnerable en nombre de la víctima ( cambio de contraseña , pregunta secreta para recuperar contraseña, correo, agregar un administrador, etc.). También es posible explotar XSS reflejado detectado en otro servidor usando CSRF .
El ataque se lleva a cabo colocando un enlace o un script en una página web que intenta acceder a un sitio en el que el usuario atacado es conocido (o presumiblemente) ya autenticado. Por ejemplo, el usuario Alice podría estar navegando por un foro donde otro usuario, Bob , publicó un mensaje. Deje que Bob cree una etiqueta <img> , en la que especificó la URL como fuente de la imagen , al hacer clic en ella, se realiza una acción en el sitio web del banco de Alice, por ejemplo:
bob: hola alicia! Mira qué lindo es este gato: <img src="http://bank.example.com/?account=Alice&amount=1000000&for=Bob">Si el banco de Alice almacena la información de autenticación de Alice en una cookie , y si la cookie aún no ha caducado, al intentar descargar la imagen , el navegador de Alice enviará una cookie en la solicitud de transferencia de dinero a la cuenta de Bob, lo que confirmará la autenticación de Alice. Así, la transacción se completará con éxito, aunque su confirmación ocurrirá sin el conocimiento de Alice.
Todas las solicitudes que modifican datos en el servidor, así como las solicitudes que devuelven datos personales u otros datos confidenciales, deben protegerse.
La forma más sencilla de protegerse contra este tipo de ataque es exigir a los sitios web que soliciten la confirmación de la mayoría de las acciones del usuario y verificar el campo HTTP_REFERER si se especifica en la solicitud. Sin embargo, este método puede ser peligroso y no se recomienda [2] .
Otro método común de protección es un mecanismo en el que se asocia una clave única secreta adicional con cada sesión de usuario, diseñada para cumplir con las solicitudes. La clave secreta no debe pasarse en claro, por ejemplo, para solicitudes POST , la clave debe pasarse en el cuerpo de la solicitud, no en la dirección de la página. El navegador del usuario envía esta clave como parte de los parámetros de cada solicitud, y el servidor verifica esta clave antes de realizar cualquier acción. La ventaja de este mecanismo, en comparación con la comprobación de Referer, es la protección garantizada contra ataques CSRF. Las desventajas son el requisito de la posibilidad de organizar sesiones de usuario, el requisito de generación dinámica de código HTML para las páginas del sitio, así como la necesidad de protección contra XSS y otros ataques que permiten a un atacante obtener una clave única.
La especificación del protocolo HTTP/1.1 [3] define métodos de solicitud seguros como GET, HEAD, que no deberían cambiar los datos en el servidor. Para tales solicitudes, siempre que el servidor cumpla con la especificación, no es necesario aplicar la protección CSRF.
Es posible que desee ir a lo seguro y agregar una clave a cada solicitud, pero tenga en cuenta que la especificación HTTP/1.1 [3] permite la presencia de un cuerpo para cualquier solicitud, pero para algunos métodos de solicitud (GET, HEAD, DELETE) la semántica del cuerpo de la solicitud no está definida y debe ignorarse. Por lo tanto, la clave solo se puede pasar en la propia URL o en el encabezado de la solicitud HTTP. Debe proteger al usuario de la distribución inadvertida de la clave como parte de una URL, como en un foro donde la clave podría estar disponible para un atacante. Por lo tanto, las solicitudes con una clave en la URL no deben usarse como la dirección a la que ir, es decir, evite ir a dicha dirección mediante el script del cliente, la redirección del servidor, la acción del formulario, el hipervínculo en la página, etc. para ocultar la clave incluida en la URL. Solo se pueden usar como solicitudes internas mediante un script que use XMLHttpRequest o un contenedor como AJAX .
Es fundamental que la clave (token CSRF) no esté destinada a una solicitud o formulario específico, sino a todas las solicitudes de los usuarios en general. Por lo tanto, basta con filtrar un token CSRF de una URL que realiza una acción simple o ninguna acción, para que cualquier acción, no solo aquella con la que está asociada la URL ahora conocida, pierda protección contra la falsificación de solicitudes.
Existe una versión más rígida del mecanismo anterior, en el que se asocia una única clave de un solo uso a cada acción. Este método es más difícil de implementar y demanda recursos. El método es utilizado por algunos sitios y portales, como Livejournal , Rambler , etc. Para 2016, no había información sobre la ventaja de una opción más rígida en comparación con la opción que usa una sola clave secreta para cada sesión [4] .