Skip to main content

Ataque a la cadena de suministro de Polyfill inserta malware en recursos JavaScript de CDN

Escrito por

26 de junio de 2024

0 minutos de lectura

Uncovering the Polyfill.io Supply Chain Attack

El 25 de junio de 2024, el equipo de investigación de seguridad y malware de Sansec anunció que un actor extranjero identificado como una empresa de origen chino había tomado el control de un popular proyecto de polyfill de JavaScript e insertaba código malicioso en recursos JavaScript obtenidos de su CDN en: cdn.polyfill.io. Sansec afirma que este ataque de polyfill afectó a más de 100,000 sitios web, incluidos los de empresas que cotizan en bolsa, como Intuit y otras.

Preguntas frecuentes

¿Snyk se vio afectado por el ataque a la cadena de suministro de Polyfill?

No, la plataforma de Snyk, incluidas nuestras herramientas, no se ve afectada por el ataque actual a la cadena de suministro de Polyfill.

¿Snyk puede detectar el problema de seguridad de Polyfill?

Snyk Code, nuestro motor SAST en tiempo real basado en aprendizaje automático, puede detectar diversos usos de URL en código funcional, incluidos JavaScript, PHP y muchos otros lenguajes.

Aquí tienes un ejemplo de regla personalizada de Snyk Code que puedes agregar:

custom_rules:
  - id: Polyfill supply chain compromise
    description: >-
      The polyfill.js is a popular open source library to support older
      browsers. This domain was caught injecting malware on mobile devices via
      any site that embeds cdn.polyfill.io.
    severity: high
    cwe:
      - CWE-506
    fix_analysis: Use alternatives provided at https://cdnjs.cloudflare.com/polyfill
    rule_code: >-
      StringLiteral<~".*http(s)?://((cdn\.)?polyfill\.io).*">
    languages:
      - html
      - javascript
      - php
      - java

Esta regla detectará correctamente el uso de cualquier URL de cdn.polyfill.io en código JavaScript o PHP. Por ejemplo, detectará la inclusión manual del script en este fragmento de código:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Load Polyfill</title>
</head>
<body>
    <script>
        // Load the polyfill for Array.prototype.includes from cdn.polyfill.io
        (function() {
            var script = document.createElement('script');
            script.src = "https://cdn.polyfill.io/v3/polyfill.min.js?features=Array.prototype.includes";
            script.onload = function() {
                // Polyfill is loaded, you can use Array.prototype.includes safely now
                console.log([1, 2, 3].includes(2)); // Should log 'true'
            };
            document.head.appendChild(script);
        })();
    </script>
</body>
</html>

Nota: la regla personalizada solo coincidirá con código JavaScript o PHP, no con etiquetas <script src=“…”></script> simples en HTML.

¿Debo agregar una regla de lista de bloqueo solo para el sitio web cdn.polyfill.io?

En muchos informes se ha registrado que el actor malicioso agregó dominios nuevos, entre ellos: polyfill[.]site, polyfill[.]com, bootcdn[.]net, bootcss[.]com, staticfile[.]net, staticfile[.]org, unionadjs[.]com, xhsbpza[.]com, union.macoms[.]la y newcrbpc[.]com. Te recomendamos encarecidamente que supervises estos informes de cerca y actualices tu regla personalizada de Snyk Code según corresponda.

¿Qué ocurrió con la biblioteca polyfill maliciosa?

En febrero de 2024, una empresa china anunció que adquiriría el sitio web polyfill.io de Jake Champion, creador de Node.js polyfill-library, y del propietario del sitio web. La empresa china Funnull, que ofrecía servicios de CDN y alojamiento, intervino y desde entonces es propietaria del dominio, la organización de GitHub y el repositorio.

Página del sitio web de Funnell que muestra el encabezado “Anuncio de adquisición de Polyfill” y un texto sobre la adquisición de Polyfill por parte de Funnell.

Poco después del anuncio de esta adquisición, el dominio polyfill.io empezó a apuntar mediante un nuevo CNAME a polyfill.io.bsclink.cn.

En círculos de desarrolladores surgieron señales de esta catástrofe inminente, como el siguiente comentario de GitHub de Renaud Chaput:

Polyfill.io era propiedad del equipo web del Financial Times, luego pasó a estar bajo la administración de la comunidad y, finalmente, el último encargado de mantenimiento vendió el proyecto a una extraña empresa china de CDN. Esta la sacó de Fastly (la plataforma de CDN y computación perimetral que ejecutaba el código de código abierto del servicio) y empezó a manipular los archivos que se enviaban.

Renaud Chaput

Durante abril y junio, usuarios de la comunidad también dieron más señales de malas prácticas y alertaron sobre la transferencia de propiedad a una empresa externa. Las sospechas aumentaron aún más cuando sus comentarios se eliminaron de un issue de GitHub:

Señales de irregularidades en la transferencia de propiedad de polyfill.io a una empresa china externa, posteriormente acusada de distribuir código malicioso para una biblioteca de polyfills de JavaScript

Andrew Betts, colega de Jake Champion en Fastly, fue el autor original del servicio web polyfill. Este proyecto permitía insertar automáticamente bibliotecas polyfill de JavaScript en sitios web según el agente de usuario u otras propiedades. Las declaraciones de Andrew se remontan a febrero, cuando advirtió que no tenía relación alguna con el sitio web oficial cdn.polyfill.io.

No conocemos ninguna biblioteca polyfill específica en npm que forme parte de esta campaña de un actor malicioso para insertar código dañino. Dicho esto, bibliotecas de distintos ecosistemas de software, como los sistemas de gestión de contenido, incluido el proyecto Magento, podrían incluir código que agrega importaciones estáticas de scripts JavaScript desde cdn.polyfill.io. En particular, detectamos CVE-2024-38526, un aviso de seguridad para la biblioteca pdoc del registro PyPI, que ofrece documentación de API para proyectos de Python. Cuando la documentación se genera con el comando pdoc --math, puede contener enlaces a archivos JavaScript de polyfill.io. Este comportamiento de la biblioteca pdoc se corrigió en la versión 14.5.1 de pdoc y recomendamos a los usuarios actualizar cuanto antes.

¿Cuál es la situación actual del sitio web polyfill.io?

El sitio web polyfill.io está prácticamente fuera de línea. Como medida adicional para proteger a los usuarios finales, extensiones de navegador que bloquean anuncios, como uBlock, ya han tomado en cuenta los informes sobre el sitio web polyfill.io y bloquean activamente el acceso para mantener a salvo a los usuarios.

Filtro de uBlock

El 21 de junio, se informó que Google lanzaría un mensaje de error de “sitio web comprometido” en el sitio web de la aplicación Google Ads, tras varios informes de intentos de suplantación de identidad desde el dominio googie-anaiytics[.]com.

¿Qué impacto tiene el malware de polyfill.io?

En 2017, Andrew Betts, autor original del sitio web polyfill.io, alojado en Fastly, informó que se realizaban nada menos que 91 millones de solicitudes diarias para importar la biblioteca y hasta 700 millones de solicitudes mensuales para actualizar navegadores antiguos con estándares web modernos.

91 millones de navegadores se actualizan automáticamente cada día con las funciones más recientes de la web.

En redes sociales y otras fuentes se ha señalado que el sitio web de Hulu incluye la biblioteca JavaScript del sitio cdn.polyfill.io, que resultó ser maliciosa (informe de Theo).

El sitio web de Hulu incorpora el código de la biblioteca JavaScript maliciosa de cdn.polyfill.io

En otro informe de Germán Fernández, también se identificó que el sitio web de la comunidad de Atlassian importa la biblioteca polyfill de JavaScript desde el dominio malicioso polyfill.io.

El sitio web de la comunidad de Atlassian incluye código fuente JavaScript del dominio polyfill.io, señalado por inyectar malware.

Silent Push Labs también identificó sitios web gubernamentales que incluían la fuente maliciosa polyfill.io y lo informó a CISA.

¿Qué es un polyfill de JavaScript?

Un polyfill de JavaScript suele ser un fragmento de código diseñado para proporcionar funcionalidades modernas a navegadores antiguos que no las admiten de forma nativa. Históricamente, los polyfills fueron esenciales para los desarrolladores web que buscaban crear aplicaciones que funcionaran sin problemas en distintas versiones de navegadores. Funcionan como un puente que permite que los navegadores antiguos ejecuten funciones nuevas de JavaScript y ofrece una experiencia de usuario uniforme, sin importar la antigüedad o las capacidades del navegador.

En los primeros años del desarrollo web, los navegadores evolucionaban a distintos ritmos y generaban un entorno fragmentado en el que el mismo código no se ejecutaba de manera uniforme en todas las plataformas. En general, la compatibilidad con las API de los navegadores no era uniforme. Como los desarrolladores no podían controlar las versiones de los navegadores disponibles para los usuarios finales, tampoco podían garantizar que una misma API estuviera disponible al ejecutar código JavaScript en el navegador. Por eso surgieron los polyfills como solución: estas bibliotecas permitían a los desarrolladores escribir código JavaScript moderno sin preocuparse por problemas de compatibilidad. Por ejemplo, navegadores antiguos como Internet Explorer no admitían métodos como Array.prototype.includes y Promise. Aun así, los desarrolladores podían habilitar estas funciones cargando una biblioteca polyfill en el navegador.

La función de una CDN de JavaScript en las bibliotecas polyfill

Una red de distribución de contenido (CDN) es un sistema de servidores distribuidos en todo el mundo que entrega contenido web a los usuarios según su ubicación geográfica. En el caso de las bibliotecas polyfill de JavaScript, las CDN cumplen una función clave: alojan y distribuyen estas bibliotecas de forma eficiente en todo el mundo. Al aprovechar las CDN, los desarrolladores se aseguran de que los polyfills lleguen a los usuarios de forma rápida y confiable, lo que reduce la latencia y mejora los tiempos de carga. El uso de una CDN también ayudaba a los desarrolladores a evitar tener que incluir las bibliotecas JavaScript en sus paquetes.

Un caso de uso común de una CDN que probablemente encontrarás es el de las métricas y el rendimiento de aplicaciones basados en la nube, como Google Analytics, que recomienda agregar el siguiente código a tu sitio web:

<script async custom-element="amp-analytics" src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>
<amp-analytics type="gtag" data-credentials="include">
<script type="application/json">
{
  "vars" : {
    "gtag_id": "<GA_MEASUREMENT_ID>",
    "config" : {
      "<GA_MEASUREMENT_ID>": { "groups": "default" }
    }
  }
}
</script>
</amp-analytics>

En el caso de la toma de control maliciosa de polyfill, cdn.polyfill.io era una CDN de uso extendido que distribuía polyfills dinámicamente según los encabezados HTTP de las solicitudes entrantes. Esto permitía entregar el polyfill adecuado según el navegador y la versión del usuario, lo que garantizaba una compatibilidad óptima.

Riesgos de seguridad de los polyfills alojados en una CDN

El uso de polyfills alojados en una CDN conlleva riesgos de seguridad importantes, principalmente por la posibilidad de ejecutar código JavaScript arbitrario dentro del contexto de la aplicación. Este riesgo suele notificarse como una vulnerabilidad de scripting entre sitios (XSS) en una aplicación web.

Cuando una aplicación obtiene una biblioteca polyfill de una CDN, depende de la integridad y seguridad del servidor externo, es decir, de la fuente de la CDN. Si la CDN o la biblioteca alojada se ve comprometida, como ocurrió en el reciente ataque a cdn.polyfill.io, se puede insertar el nuevo código comprometido y ejecutarlo en el navegador del usuario. Ese código malicioso puede realizar diversas actividades dañinas, como redirigir a los usuarios a sitios de phishing, robar información confidencial o incluso propagar más malware. En lo que respecta a la seguridad del navegador, este tipo de vulnerabilidad XSS es la consecuencia más grave.

Cómo protegerse contra ataques a la cadena de suministro de CDN

El reciente ataque al proyecto polyfill de JavaScript destaca la importancia crítica de respaldar los recursos de todo el ecosistema web, y las CDN son una parte importante de ese ecosistema. Las preocupaciones sobre la seguridad de la cadena de suministro suelen centrarse en los registros de paquetes de código abierto, como PyPI y npm, pero el ataque a polyfill de JavaScript nos recordó que las CDN también son un componente fundamental de la web.

A continuación, encontrarás algunas prácticas recomendadas que puedes seguir para protegerte contra este tipo de ataques:

  • Usa CDN confiables: usa solo CDN de proveedores de buena reputación. Por ejemplo, Cloudflare es conocida por sus sólidas medidas de seguridad y confiabilidad.

  • Reemplaza Polyfill: Cloudflare creó un clon de polyfill en https://cdnjs.cloudflare.com/polyfill, que recomienda usar como reemplazo directo.

  • Supervisa las dependencias: audita y supervisa periódicamente todos los scripts y dependencias de terceros.

  • Integridad de subrecursos: herramientas como Subresource Integrity (SRI) pueden ayudar a garantizar que el contenido entregado por una CDN no se haya manipulado. También permiten fijarlo a una versión o un hash esperado que se haya auditado y se sepa que está libre de comportamientos maliciosos o no deseados.

  • Política de seguridad de contenido (CSP): implementa una CSP sólida para restringir las fuentes desde las que se pueden cargar scripts. Esto puede impedir que se ejecuten scripts maliciosos. Como los polyfills suelen formar parte de la ruta crítica de carga de una aplicación, se ejecutan con los mismos permisos que cualquier otro JavaScript de la página, lo que los convierte en un objetivo prioritario para los atacantes que buscan aprovechar esta confianza. Este riesgo destaca la importancia de usar CDN seguras y confiables, implementar medidas de seguridad sólidas, como la Política de seguridad de contenido (CSP), y auditar periódicamente las dependencias de terceros para protegerse contra este tipo de vulnerabilidades.

  • Actualizaciones periódicas: mantén actualizadas todas las bibliotecas y dependencias. Muchos ataques aprovechan vulnerabilidades conocidas que se corrigieron en versiones posteriores.

  • Soluciones alternativas: evalúa si tu proyecto todavía necesita polyfills. A medida que los navegadores se modernizan, muchas de las funciones que proporcionan los polyfills ya son compatibles de forma nativa. Considera seriamente incluir las dependencias en los recursos de tu propio proyecto, en lugar de depender de proveedores externos, como las CDN.