Cómo evita Pornhub a los bloqueadores de anuncios usando WebSockets

Los desarrolladores de BugReplay explican como Pornhub es capaz de servir anuncios usando WebSockets a clientes con bloqueadores instalados.

Cuando los desarrolladores de BugReplay (un servicio online para grabar vídeos del navegador junto con la consola Javascript) estaban evaluando diferentes métodos para capturar y analizar el tráfico de red en Chrome, se fijaron en la API chrome.webRequest. Según la documentación esta API permitía analizar y observar el tráfico y, lo mejor de todo, interceptar, bloquear o modificar peticiones. Pero tras investigar un poco su funcionamiento, se dieron cuenta que tenía un gran inconveniente: no permitía analizar el tráfico WebSocket.

En la documentación no encontraban nada que les indicara que estaban equivocados, pero lo que si encontraron fue un bug report de 2012 titulado “chrome.webRequest.onBeforeRequest doesn’t intercept WebSocket requests”. En este reporte los usuarios se quejaban de que esta imposibilidad de bloquear WebSockets permitiría a las webs ignorar los bloqueadores de anuncios (AdBlock y similares).

Los bloqueadores de anuncios en Chrome utilizan la API webRequest para bloquear la carga de scripts e imágenes en función de ciertas reglas que actualizan cada poco tiempo. Si los WebSockets no podían ser bloqueados de ninguna forma, nada impediría a una web enviar contenido dentro de un WebSocket para ser mostrado usando Javascript en el cliente.

Pornhub se salta los bloqueadores de anuncios con WebSockets

En Agosto de 2016 un empleado de la compañía MindGeek (dueña de Pornhub.com) empezó a dar argumentos en contra de añadir el bloqueo de WebSockets a la API de Chrome. Si entrábamos en sitios de MindGeek (Pornhub y otros asociados) podíamos ver publicidad proporcionada por su propia red (Traffic Junky) incluso con el bloqueador de anuncios activado, así que todo indicaba a que ellos conocían esta pequeña “laguna” en la API.

pornhub
Pese a que Pornhub detecta que usamos un bloqueador de anuncios, nos los sigue mostrando.

En la imagen se puede ver cómo Pornhub avisa al usuario de que está usando un bloqueador de anuncio. Sin embargo, sigue mostrándolos pese a que tenemos activador el bloqueador.

Cómo lo hacen

Cuando visitamos Pornhub, el sitio intenta detectar si utilizamos un bloqueador de anuncios. Si lo detecta, abre una conexión WebSocket que actúa como mecanismo de backup para mostrar anuncios. Si miramos este vídeo podemos ver las peticiones bloqueadas por AdBlock y marcadas como tráfico fallido con el error net::ERR_BLOCKED_BY_CLIENT. Este error es el que reporta Chrome cuando un recurso es bloqueado al cargar.

Para usar el WebSocket para servir anuncios, Pornhub crea un WebSocket con información del anuncio que va a cargar. La información que contiene es:

  • Dónde va a colocarse el anuncio (zone_id).
  • Tipo de anuncio, ya que puede ser un vídeo o una imagen (media_type).
  • Si es una imagen, su codificación en base64 usando el esquema de URI de datos.
  • Si es una imagen, el tipo de imagen (normalmente es “image/jpeg”).

Los bloqueadores de anuncios funcionan principalmente con la API webRequest, así que construir y transmitir el anuncio usando WebSockets es una forma muy inteligente de saltarse este bloqueo.

Posibles soluciones

En Octubre de este mismo año, alguien escribió un parche añadiendo que los WebSockets pudieran ser bloqueados por la API webRequest, aunque aún no sido añadido a las versiones estables de Chrome. Bloqueadores como Adblock Plus o uBlock Origin ya han creado algunos parches para tener en cuenta este problema.

Adblock Plus por ejemplo lo que hace es crear una petición de prueba antes de que los mensajes WebSocket sean enviados/recibidos. La extensión reconoce estas peticiones de prueba como “representantes” del mensaje WebSocket. De esta forma puede interceptarlos y bloquear el WebSocket si alguno debe ser bloqueado. uBlock Origin sin embargo utiliza una directiva CSP para dicho fin.

Ahora habrá que esperar a que el equipo de desarrollo de Chrome apruebe el parche de la comunidad para que su API webRequest sea capaz de bloquear WebSockets.

Enlaces relacionados