Autor: Samuel Lopez Saura
CSRF son las siglas de Cross Site Request Forgery. Esto es
una técnica a través de la cual un usuario víctima realiza determinadas
acciones programadas sin ser consciente de ello.
Imaginémonos el siguiente escenario.
El usuario A es administrador del sitio web
empresadeejemplo.com
Dentro de empresadeejemplo.com puede realizar las siguientes
acciones.
•
Ver empleados de la
empresa
•
Ver nómina de un empleado
•
Subir sueldo a un
empleado
•
Ver mi sueldo
•
Mi historial
El sitio web empresadeejemplo.com tiene un mecanismo de
sesiones y solo permite que el usuario admin realice las acciones marcadas en
rojo.
Para subir el sueldo de un empleado se encuentra con el
siguiente escenario.
El usuario administrador elige un usuario, la cantidad a
subir su sueldo y al darle a enviar genera una URL tal que
Dentro de la petición HTTP se manda la Cookie de sesión del
administrador. La aplicación comprobará que la cookie de sesión es válida y que
pertenece a un usuario con privilegios administrativos.
Dentro del código de la aplicación habrá algo parecido a
esto:
$usuario = $_REQUEST[‘usuario’];
$aumento = $_REQUEST[‘aumento’];
→ si el usuario al que corresponde la sesión es admin
subir_sueldo($usuario,
$cantidad);
header(‘Location:
/admin’); /* Redirigimos al panel de administración */
→ si el usuario
al que corresponde la sesión no es admin
header(‘Location:
/’); /* Redirigimos a la raíz del sitio
*/
La aplicación funcionaría y en principio un usuario que no
fuera admin no podría realizar la acción.
La pregunta es, ¿qué pasaría si admin hiciera clic en http://empresadeejemplo.com/admin/subirsueldo.php?usuario=juan_ejemplo_perez&aumento=9000
sin ser consciente de ello?
Su navegador realizaría una petición GET y mandaría su cookie de sesión el servidor
comprobaría que realmente es admin quién está realizando la acción y subiría en
9000€ el sueldo al empleado juan ejemplo perez.
Pero ¿cómo va a hacer clic en eso el administrador? Volvamos
atrás, cuando hacemos clic emitimos una petición GET al servidor y esta la
procesa. Esta petición también la realizamos cuando, por ejemplo, cargamos una
imagen. Entonces si el usuario administrador visitara un sitio web que cargase
esa URL su navegador emitiría una petición GET al servidor como si el propio
administrador conscientemente hiciera la petición.
< img src=” http://empresadeejemplo.com/admin/subirsueldo.php?usuario=juan_ejemplo_perez&aumento=9000”/>
– Una imagen dice más de
mil palabras
Además, ¿y si los datos se pasaran
por el método POST en lugar de por el método GET?
Desde PHP podemos recibir
parámetros con $_GET, $_POST, $_REQUEST. El primero contiene un array
asociativo con los datos mandados por el método GET. El segundo por el método
POST y el tercero por cualquiera de los dos métodos.
La utilización de $_REQUEST es una
práctica muy común y sin una validación adecuada podemos enviar en un método
GET parámetros que el servidor procesaría como si fuera un método POST para un
campo que se espera ser recibido solo por POST. Es decir, en una URL podríamos
simular un “POST” implícito en ella si al recibir el parámetro lo recibiéramos
mediante $_REQUEST.
junto a un método POST los
parámetros de usuario y aumento.
Sería igual a la url → http://empresadeejemplo.com/admin/subirsueldo.php?usuario=juan_ejemplo_perez&aumento=9000
Si el documento PHP tuviese en
cuenta por donde vienen los datos. Utilizando $_POST o $_GET en lugar de la
opción genérica $_REQUEST. Y la acción fuera dada por el método POST habría que
simular el envío de un formulario con esos valores al servidor pero el
mecanismo sería muy similar a la opción de la imagen con la excepción de que
sería un código javascript quién realizase la petición POST o activase el envío
de un formulario.
La tarde del miércoles creé una
micro aplicación que bajo un fin educativo automatizaba este proceso.
Arriba a la derecha tenemos un
botón que pone Nueva URL. Esto levantará una ventana donde podremos poner los
parámetros.
Lo que nos genera una URL como la
siguiente:
http://cj.curiosoinformatico.com/?r=http://honeycon.eu&YfwEijRLSOJqYRvvzucaTDD6abLA0rZrPKaTpxSEmWAjoJpGjYVPvSEq8XHZzLsSYlIA9reFyahfWUjVolTN3q2JtU5C6y7Q6jZT&c=http://empresadeejemplo.com/admin/subirsueldo.php?usuario=juan_ejemplo_perez&aumento=9000
Cuando copiemos la URL y la
peguemos en la barra del navegador nos encontraremos con esto:
Lo que está pasando en realidad es
lo siguiente:
• Se
accede a http://cj.curiosoinformatico.com, lo primero en cargar es un script que comprueba si
tenemos parámetros en la URL que nos indiquen a donde redirigir y donde hacer
clic.
• De tenerlos carga el sitio que hemos escogido para hacer
clic como una imagen nada sospechosa y cambia la URL del documento al sitio
destino.
• No obstante como la URL es un poco sospechosa podemos usar
un acortador de enlaces como bit.ly para hacerla más confiable.
¡Magia!
Esta poderosa URL subirá nuestro sueldo en 9000 euros sin que nadie se entere y
le informará a nuestro jefe de un evento donde aprender y mejorar su seguridad.
http://bit.ly/2ea3VFM
Nota del autor: Actualmente
la página no tiene soporte para peticiones POST -si tiene para GET y para los POST
que recoja PHP a través de $_REQUEST (que en realidad se envían como GET)-.
Imagino que en un hueco libre que tenga se lo pondré pero si alguien quiere
adelantarse aquí dejo el github del mismo.
https://github.com/curiosoinformatico/two_steps_redirector
Tras publicar este articulo Vicente Aguilera Diaz se puso en contacto con nosotros y nos indico varios interesantes enlaces de sus publicaciones sobre CSRF y redes sociales, aquí podéis consultarlos:
Caso Facebook: http://www.isecauditors.com/advisories-2011#2011-002
Caso Linkedin: http://seclists.org/fulldisclosure/2013/Mar/216
Caso Gmail: http://www.securiteam.com/securitynews/5ZP010UQKK.html
Muchas gracias Vicente.
******************* ACTUALIZACIÓN *********************
Tras publicar este articulo Vicente Aguilera Diaz se puso en contacto con nosotros y nos indico varios interesantes enlaces de sus publicaciones sobre CSRF y redes sociales, aquí podéis consultarlos:
Caso Facebook: http://www.isecauditors.com/advisories-2011#2011-002
Caso Linkedin: http://seclists.org/fulldisclosure/2013/Mar/216
Caso Gmail: http://www.securiteam.com/securitynews/5ZP010UQKK.html
Muchas gracias Vicente.
No hay comentarios:
Publicar un comentario