Cross-Site Request Forgery es un ataque que fuerza a la victima a realizar acciones no deseadas en una aplicación en la que ésta se encuentra autenticada.
Como funciona este ataque? Un ejemplo simple, podría ser el siguiente, pongámonos en la situación de un servlet de un banco que permite realizar transacciones.
Este servlet, usa los siguientes parámetros (acct y amount), veamos un ejemplo de petición HTTP:
POST http://bank.com/transfer.do HTTP/1.1
...
...
Content-Length: 19;
acct=BOB&amount=100
En account se establece la cuenta de destino y en amount el dinero a transferir. En este escenario, un atacante puede crear un formulario de tipo POST, que envíe esas dos variables al servlet, y preparar una página web en la cual este formulario se envie de manera automática mediante JavaScript. El atacante incita a la victima a visitar este enlace y directamente la transferencia se realiza sin intervencción por parte del usuario.
El atacante ha conseguido que la victima ejecute acciones no deseadas, ya que ésta dispone de una sesión válida en la aplicación.
Del mismo modo, la interfaz móvil de Facebook era vulnerable en el formulario de actualización del perfil a ataques de tipo CSRF, en concreto en el recurso http://m.facebook.com/a/editprofile.php
El siguiente código, es un ejemplo que permite a un atacante modificar el número de teléfono en el perfil mediante esta técnica. Preparando el siguiente formulario para que se envíe automáticamente, haciendo que sea accesible en una página web y tratar que la victima lo visite mediante el envío de un enlace o cualquier otro método, concluiría en el compromiso del usuario y de la aplicación por parte del atacante:
Prueba de concepto:
<html>
<head>
<script>
function send() {
document.forms[0].submit();
}
</script>
</head>
<body onload="send();">
<form action="http://m.facebook.com/a/editprofile.php?edit=phone_cell&type=contact"; method="post">
<input type="hidden" name="phone_num" value="600000000">
<input type="hidden" name="save" value="">
</form>
</body>
</html>
El impacto es que un atacante puede forzar a otros usuarios de Facebook a realizar acciones no deseadas. La explotación con éxito de este ataque permitía la actualziación del perfil de la víctima.
Mitigación:
Es necesario implementar mecanismos de control con el objetivo de asegurar que el usuario además de estar autenticado y disponer de permisos para realizar una acción determinada (autorizado), no está siendo forzado por otros usuarios a realizar acciones no deseadas mediante CSRF.
Para resolver este problema, hay varias soluciones, la más común, se trata de generar un token aleatorio al crear el formulario y almacenarlo con la información relacionada a él (recurso, usuario, perfil, formulario, etc), añadiéndolo como campo oculto en el formulario.
Una vez se realiza la petición contra el servidor, se valida que ese token es válido. Un atacante que prepare un formulario malintencionado no podrá saber que token es válido y cúal no, por lo que con esta medida mitigamos el ataque.
El equipo de seguridad de Facebook fue notificado lo antes posible en cuanto se descubió la vulnerabilidad y corrigió este bug de forma rápida, por lo que actualmente está solucionado.
Disponeis del advisory original enviado a Full-disclosure:
http://seclists.org/fulldisclosure/2010/Feb/274
Muchas gracias! al equipo de seguridad de Facebook y a SecurityByDefault @secbydefault por las reseñas ;-)