sábado, 25 de octubre de 2008

Cross-Site Request Forgery.


A nuestro usuario Pepito le gusta comprar en Amazon y adquiere un par de libros de cuando en cuando. Un día recibe un correo confirmando una compra que no hizo; por otro lado también tiene listado como favorito un video de YouTube que nunca enlistó y su sitio favorito de correo web ya no lo reconoce. ¿Una maldición? No tanto así, sólo fue víctima del Cross-Site Request Forgery.

¿Esto del cross-site request forgery no es lo mismo que el cross-site scripting? No, son ataques diferentes. Antes de adentrarnos en los detalles explico brevemente lo que es: cuando una víctima visita un sitio malicioso (o abriendo un correo HTML maligno), un atacante puede capturar la información almacenada en la computadora (cookies) de una sesión previamente establecida y reenviarla (junto con ciertas instrucciones adicionales) a un sitio en mi nombre pero sin mi conocimiento o permiso. Bueno, es una explicación muy resumida, vayamos a lo detalles (pueden saltárselos y pasar a la última parte para prevenir este ataque).

Empecemos. Primero vamos a hablar de los métodos POST y GET para luego pasar al tema de las cookies; ambos son los pilares para este ataque. Bien, para recibir información de un servidor (por ejemplo cuando queremos visitar www.google.com), un navegador usa el protocolo HTTP para pedir esa página en particular. Y para lograrlo, usa los métodos GET o POST. Estos métodos los ve uno en un sniffer cuando un navegador pide una página. Es simplemente un navegador diciendo a Google, "hey!, dame tu página principal" o "hey! dame la página www.google.com/policies". Por ejemplo, en un sniffer el método GET o POST se vería así:

207.218.76.48 -> www.google.com GET /agenhtml/agenmc/icons/balls/red.gif HTTP/1.0

Ahora bien, algunas páginas tienen formularios que piden enviar datos como mi nombre o edad, y dichos formularios aprovechan el método GET y usan un signo de interrogación "?" indicando que lo que viene después son los datos que inserta el usuario; por ejemplo buscando la palabra jabón en google:

www.google.com.mx/search?hl=es&q=jabón&btnG=Buscar+con+Google&meta=


Por otro lado, POST enviaría esos mismos datos como mi nombre o edad pero encapsulando los datos en los paquetes HTTP. Lo importante de recordar es que cuando visito una página o recibo un mail, hay varios métodos GET que por ejemplo le traen una imagen a mi navegador. Concretamente, recibo un mail en Outlook y al abrirlo contiene HTML e imágenes; lo que hace en ese momento Outlook (usndo IE) es ir al sitio web por las imágenes con un método GET (o POST) y traerlas para que las pueda ver. En fin, para más información de estos métodos, pueden googlear POST GET, o visitar esta página o esta otra.

Una vez comentado lo anterior de POST y GET, expliquemos un segundo elemento en el cross site request forgery que son las cookies. Sabrán que las "galletas" son archivos que se almacenan en sus computadoras para evitar que un usuario se esté constantemente autenticando en un sitio. Por ejemplo, me meto a www.amazon.com y la siguiente vez que voy al sitio, "mágicamente" despúes de teclear el sitio en mi navegador ya el sitio me reconoce e ingreso directamente a mi cuenta...cómo lo logró? Porque las cookies se encargaron de eso y me evitaron la molestia; son cookies persistentes. De hecho las cookies se usan para mantenerme validado/autenticado con Amazon mientras navego en sus diferentes páginas, de otro modo no me recordaría entre una y otra página.

Bueno, ahora viene el ataque (por fin). Ejemplifiquemos con Amazon. Recibo un correo HTML que tiene una referencia a una imagen para que Outlook la busque en "X" sitio. Pero esa referencia realmente no trae una imagen, es un GET a Amazon que pide comprar un artículo. Recordemos que Amazon tiene una característica de one-click para que si un usuario ve un artíiculo en su página lo pueda comprar de inmediato y sin pasar por todo el proceso de compra con este botón one-click.

Pues bien, sin yo estar necesariamente en Amazon, este GET malicioso pide primero a Amazon desplegar un producto (yo no veo nada de esto ya que sucede de forma "subterránea" para un usuario normal), y luego el GET pedirá comprarlo con el one-click. Esto para el servidor de Amazon es perfectamente normal y de hecho es lo que un usuario normal haría: encontraría un artículo y luego lo compraría con el one-click; no hay manera de que Amazon sepa si soy yo realmente o es un GET que a mi nombre está haciendo todo esto.

El cross-site request forgery es una realidad y aunque usé a Amazon como un ejemplo, hay casos reales documentados y un muy buen paper del tema creado por William Zeller y Edward Felten que está con muchos más detalles que mi modesta explicación (lo recomiendo ampliamente). Los casos documentados son de sitios afectados por este tipo de ataque (ING, YouTube, New York Times):

www.ingdirect.com/
www.youtube.com/
www.nytimes.com/

Algunos sitios han solucionado esto.

¿Medidas preventivas?
1.- Darle "logout" a todas las páginas correspondientes cuando acabemos de visitar el sitio (con esto inhabilitamos a la cookie correspondiente).
2.- Usar en todo caso la administración de contraseñas del propio navegador (lo que hace el pre-llenado de campos en una página); al menos es inmune a este cross site request forgery.
3.- Borrar el historial del navegador periódicamente (Opciones->General->Historial de Exploración->Eliminar->Eliminar todo); esto borrará las cookies.
4.- Usar un plug in (sólo para Firefox) que se encuentra aquí.
5.- Leer correo en texto plano (plain text) y no en HTML (ya lo había comentado anteriormente).

Habrá que estar atentos a este tipo de ataques.