Las cookies son un elemento de lo más común en las aplicaciones web actuales y seguramente el lector sabe perfectamente cómo funcionan, sin embargo, para aquellos que no lo saben, basta con comentar que las cookies son ficheros temporales que se almacenan en el navegador del cliente y permiten simplificar el proceso de identificación y posterior comunicación con una aplicación web. Dado que HTTP es un protocolo sin estado, el uso de las cookies es realmente útil para conservar información que ha intercambiado previamente entre cliente y servidor. Prácticamente todos los sitios web en Internet hacen uso de las cookies, sin embargo, la información que se almacena en las cookies puede ser utilizada para identificar y perfilar a un usuario. Con las cookies se puede identificar la navegación de un usuario por un sitio web y de esta forma, tracear las páginas que visita, conociendo sus intereses y otras características del usuario. Esto no es necesariamente algo negativo, de hecho, puede ser muy beneficioso para el usuario ya que de esta forma el sitio web puede conocer sus preferencias y de esta forma, actuar en consecuencia para ofrecerle los contenidos que más le puedan interesar. Por ejemplo, en el caso de una tienda online de ropa, se pueden utilizar las cookies para saber si el usuario ha ingresado previamente en el sitio web y si ese es el caso, presentar ofertas o productos personalizados dependiendo de las páginas que ha visitado. No obstante, cuando dicha información es compartida con otros sitios web ajenos, es cuando muy posiblemente se está violando la privacidad del usuario, ya que evidentemente no ha dado un consentimiento expreso de compartir con otros sitios web las páginas que ha visitado, la información que ha podido ingresar, etc. Esto es común en sitios web dedicados a la publicidad y el marketing, los cuales utilizan la información compartida por otros sitios web para perfilar gustos, afinidades y tendencias de los usuarios, así como identificarles.
Ahora bien, las cookies son elementos que se pueden eliminar muy fácilmente del navegador y en la mayoría de casos no representarán ningún problema, sin embargo, las cookies persistentes, a diferencia de las cookies tradicionales, utilizan múltiples espacios de almacenamiento en el cliente y de esta forma, resulta muy complicado eliminar toda la información que almacena una cookie de estas características del navegador. Para que el lector se haga una idea, una cookie persistente puede almacenar información en el espacio estándar de cookies, en el espacio de “websql” del navegador, en el espacio de almacenamiento local, global y de sesión, en cookies flash (objetos locales compartidos), en la cache del navegador, entre otros. Cuando el usuario elimina dichas cookies desde uno o varios de estos espacios, pero no de todos, el sitio web que ha implementado la cookie persistente es capaz de detectar que se ha intentado eliminar la información de la cookie uno o varios de dichos espacios de almacenamiento y se encarga de reestablecer los valores, revirtiendo la acción de borrado realizada por el usuario, es decir, el usuario tiene que eliminar la información de la cookie de todos los sitios donde se ha guardado y si le falta al menos uno por limpiar, dichos valores volverán a ser replicados en todas las zonas de almacenamiento.
Las cookies persistentes representan una forma muy agresiva de tracear la navegación de un usuario y una de las más conocidas es la que ha desarrollado el investigador Samy Kamkar (también conocido por el desarrollo del virus “Samy”) la cual recibe el nombre de “evercookie”.
Uso de Evercookie
Se trata de una API que cuenta con varios elementos que desde el punto de vista técnico resultan muy interesantes, pero que desde una perspectiva practica, se relacionan más con campañas de marketing agresivas y con el perfilado de los usuarios, actividades que suelen ser consideradas ilegales. Esta herramienta cuenta con una API en Javascript que permite crear cookies persistentes que a la fecha de redactar este artículo, se incluyen en las siguientes zonas del navegador del cliente.
- Cookies HTTP estándar.
- Objetos compartidos locales (Cookies Flash).
- Almacenamiento en Silverlight
- Almacenamiento de cookies en formato RGB usando la etiqueta “canvas” de HMTL5
- Múltiples ubicaciones de almacenamiento definidas en la especificación de HTML5 (Almacenamiento local, global, sesion, WebSQL con SQLite y WebSQL con IndexedDB).
- Almacenamiento persistente en JNLP PersistenceService.
Para utilizar esta librería se debe descargar desde el repositorio de GitHub ubicado en la siguiente ruta: https://github.com/samyk/evercookie y posteriormente, se puede comenzar a utilizar la API de Javascript que permite crear páginas web que insertan una cookie de evercookie en los clientes que acceden a dichas páginas.
En esta entrada voy a explicar cómo utilizar esta librería para crear cookies persistentes y vamos a ver algunas de las zonas en las que se almacenan las cookies que se van creando.
Después de descargar o clonar el proyecto desde el repositorio de GitHub, se debe crear un fichero HTML que será incluido en un servidor web como Apache.
En este caso concreto, con el objetivo de probar el funcionamiento de Evercookie, se ha creado un directorio llamado “test” en el directorio “htdocs” de un servidor web Apache y en dicho directorio se han incluido los siguientes recursos, los cuales son los que se han obtenido del proyecto de Evercookie.
El contenido inicial de la página “index.html” es el que se indica a continuación y como se puede apreciar, no solamente incluye el script “js/evercookie.js”, sino que también se hace uso de la API para crear y almacenar cookies persistentes.
<html> <head> <script type="text/javascript" src="js/swfobject-2.2.min.js"></script> <script type="text/javascript" src="js/evercookie.js"></script> <script> var ec = new evercookie({ baseurl: '/test', asseturi: '/assets', phpuri: '/php' }); ec.set("user", "adastra"); ec.get("user", function(value) { alert("Cookie value is " + value) }); function getCookie(best_candidate, all_candidates) { for (var item in all_candidates) document.write("Storage mechanism " + item + " returned " + all_candidates[item] + " votes<br>"); } ec.get("user", getCookie); </script> </head> <body> <h1>evercookie!</h1> </body> </html>
Lo primero que hace es crear un objeto del tipo “evercookie” indicando la URI del sitio web y la ubicación de los recursos necesarios para crear la cookie. Posteriormente, las funciones “set” y “get” permiten crear y recuperar un cookie respectivamente. Como se puede apreciar, la función “get” permite definir una función de callback que tratará el valor de una cookie que se ha guardado previamente con un identificador determinado.
Aunque el código puede parecer simple, en el momento de probar la librería he experimentado algunos problemas relacionados con la adición de capas en el árbol DOM de la página, ya que al parecer, cuando Evercookie se ejecuta sobre el navegador Chrome, Evercookie intenta añadir elementos al cuerpo de la página antes de que el árbol DOM se encuentre correctamente creado, lo cual da como resultado errores similares a los que se pueden ver en la siguiente imagen.
La solución a este problema pasa simplemente por realizar una verificación previa del árbol DOM antes de intentar insertar elementos en cualquier tag. Por ejemplo, en la linea 956 del fichero “js/evercookie.js” veremos el siguiente fragmento de código:
if (append) { document.body.appendChild(el); }
Dado que en este punto el valor de “document.body” es “null”, la invocación a la función “appendChild” es invalida y produce un error. Es necesario realizar una validación previa antes de invocar a la función “appendChild”, algo tan simple como lo que se enseña a continuación será suficiente.
if (append) { if(document.body != null){ document.body.appendChild(el); } }
Después de corregir todos los errores que van saliendo y que están relacionados con el mismo problema que se ha explicado anteriormente, se puede apreciar como la cookie se crea en diferentes secciones del navegador.
Evercookie en el “Session Storage” del navegador
Evercookie en el “Local Storage” del navegador
Evercookie en la base de datos SQLite del navegador
Aunque se intente eliminar las cookies utilizando el procedimiento habitual de limpiar cache, formularios guardados, cookies, etc. Evercookie vuelve a crearse automáticamente en cada una de las zonas de almacenamiento indicadas anteriormente, convirtiéndola en un elemento difícil de remover del navegador web. Difícil, pero no imposible.
En un próximo articulo se hablará en detalle sobre las ubicaciones en las que se almacena evercookie y cómo eliminar una cookie persistente creada previamente. Por otro lado, también se hablará de implementaciones de evercookie en NodeJS y Django.
Un Saludo y Happy Hack!