SophosLabs Uncut

¡PACs proxy envenenados! Vulnerabilidad en el paquete NPM que afecta a toda la red

No hace mucho, el desarrollador de software independiente Tim Perry, creador del kit de herramientas HTTP, para interceptar y depurar el tráfico, decidió agregar soporte proxy a su producto, que, como muchos software en estos días, está escrito usando Node.js.

Por si no lo sabes, Node.js es el proyecto que sacó el lenguaje JavaScript del navegador y lo convirtió en un sistema de desarrollo de aplicaciones completo por derecho propio, un poco como Java (que no está relacionado con JavaScript, por cierto, pese a que sus nombres lo sugieran).

Además del núcleo de JavaScript, que utiliza el motor JavaScript V8 del proyecto Chromium de Google, el software Node.js generalmente también se basa en NPM, el administrador de paquetes de Node y el registro de NPM, un repositorio realmente enorme de herramientas y bibliotecas de programación de Node de código abierto.

El registro de NPM ejecuta desde el formato de texto básico hasta el reconocimiento facial completo y casi todo lo demás.

En lugar de tener que escribir tu mismo todo el código de tu proyecto, o incluso la mayor parte, simplemente haz referencia a los paquetes complementarios que deseas utilizar, y NPM los buscará por ti, junto con cualquier paquete adicional que necesites, hasta cada add-on necesario para completar el rompecabezas.

Sopa de letras

Como te puedes imaginar, esta es una posible pesadilla de seguridad.

Agregar solo un paquete a tu propio proyecto, puede requerir una gran cantidad de paquetes adicionales, cada uno de los cuales puede haber sido escrito por una persona diferente a la que no conoces y probablemente nunca lo harás.

Esta sopa de letras se conoce como el árbol de dependencia de tu software, y ya hemos escrito sobre los peligrosos efectos secundarios de este enfoque para la construcción de software, señalando que:

Es posible que descubras que puede escribir un programa JavaScript de cinco líneas que sea elegantemente simple, pero solo si tu Node Package Manager gestiona decenas o incluso cientos de miles de líneas del software de otras personas. Automáticamente. De todas partes de Internet. Y lo mantiene actualizado. Automáticamente, desde todo Internet.

El soporte proxy da problemas

Perry redescubrió este riesgo recientemente, cuando decidió utilizar un paquete de NPM popular llamado Proxy-Agent para proporcionar el soporte proxy que quería en su producto HTTP Toolkit.

Afortunadamente, Perry no buscó, instaló y comenzó a usar a ciegas Proxy-Agent y su árbol de dependencias completo sin hacer una revisión de los componentes recién adquiridos en su proyecto.

Por lo tanto, se encontró con una falla de seguridad, ahora denominada CVE-2021-23406, en una dependencia de Proxy-Agent llamada Pac-Resolver, que es un subcomponente que ayuda a tu código a lidiar con el proceso de PAC, o configuración automática de proxy.

Un servidor proxy es aquel que realiza conexiones salientes en tu nombre, generalmente por seguridad (por ejemplo, para filtrar el tráfico web), por rendimiento (por ejemplo, para mantener copias locales de archivos que se descargan con frecuencia o para regular el uso del ancho de banda durante períodos de mucha actividad), o para ambos. Te conectas al proxy y le dices a dónde quieres ir, él realiza la conexión posterior por ti, recopila las respuestas y te las devuelve. Muchas redes corporativas están configuradas para que determinadas conexiones salientes, en particular solicitudes HTTP, solo sean posibles desde un servidor proxy designado. Esto asegura que todos dentro de la red envíen su tráfico a través del proxy, en lugar de ir directamente a sitios externos. Existen numerosas herramientas empresariales para ayudar a los ordenadores en una red a ubicar sus proxies internos oficiales automáticamente, incluido PAC, abreviatura de configuración automática de proxy, y WPAD, abreviatura de protocolo de autodescubrimiento de proxy web.

Por extraño que parezca

Los archivos PAC, lo creas o no, no son solo listas de datos de números de IP o nombres de servidor donde se encuentran los servidores proxy oficiales de tu red.

Debido a que estaban destinados a ser utilizados dentro de tu navegador, los archivos PAC se diseñaron deliberadamente para ser más flexibles que solo una lista de datos estáticos.

De hecho, un archivo PAC consta de JavaScript que puede determinar dinámicamente si se necesita un proxy y, de ser así, dónde encontrarlo en la red.

Como señala Perry, el formato de archivo PAC se remonta a un cuarto de siglo y apareció por primera vez como una “función” en el navegador Netscape:

Los archivos PAC proporcionan una forma de distribuir reglas de proxy complejas, como un solo archivo que asigna una variedad de URL a diferentes proxies. Se utilizan ampliamente en entornos empresariales y, por lo tanto, a menudo necesitan ser compatibles con cualquier software que pueda ejecutarse en un entorno empresarial. [… Un archivo PAC es] un archivo JavaScript que se debe ejecutar para conectarse a Internet, que se carga de forma remota, a menudo de forma insegura y/o desde una ubicación que su red local puede decidir silenciosamente. 1996 era realmente una época más sencilla. ¿Qué podía salir mal?

Por supuesto, Perry no planeaba ejecutar archivos PAC dentro de las restricciones algo limitadas de un navegador, pero como parte de su software HTTP Toolkit, que se ejecuta como una aplicación regular, potencialmente le da al JavaScript mucho más alcance y poder que un script que se ejecuta dentro de un navegador.

Por lo tanto, decidió echar un vistazo a cómo los programadores del código de configuración de proxy que había elegido habían abordado las implicaciones de seguridad sobre obtener y ejecutar JavaScript externo.

Descubrió que el código usaba un componente de nodo llamado vm, abreviatura de máquina virtual, que le permite configurar una nueva instancia de JavaScript, o estado, donde no interferirá con el código que se ejecuta en otras instancias de nodo de su aplicación.

Esta es una precaución útil si deseas que dos partes de tu código hagan cosas separadas de tal manera que no puedan pisotearse entre sí por error.

En palabras de la documentación de la biblioteca vm:

El módulo vm permite compilar y ejecutar código en contextos de máquina virtual V8. […] El código JavaScript puede compilarse y ejecutarse inmediatamente o compilarse, guardarse y ejecutarse más tarde. Un caso de uso común es ejecutar el código en un contexto V8 diferente. Esto significa que el código invocado tiene un objeto global diferente al código invocador.

Perry se dio cuenta de que el programador original, cuyo código había adoptado ahora, estaba usando la biblioteca vm tanto para seguridad programática como para un mecanismo seguridad, aparentemente asumiendo que una nueva instancia de VM no solo estaba separada de otras instancias de VM en la aplicación, sino también estrictamente sandboxed en su propio mundo aislado de JavaScript.

Sin embargo, como deja claro la documentación de vm, en letra negrita:

El módulo vm no es un mecanismo de seguridad. No lo use para ejecutar código que no sea de confianza.

Perry, rápidamente descubrió cómo usar una técnica de programación JavaScript regular para ejecutar código dentro de la nueva instancia de vm que tenía acceso completo a los datos externos de su aplicación principal Node.js.

Técnicamente, eso constituye un error de RCE en el proceso de configuración del proxy, donde RCE es la abreviatura de ejecución remota de código.

En términos generales, RCE significa que el contenido que no es de confianza obtenido de una fuente que no es de confianza puede hacer deliberadamente algo malicioso que se supone que no está permitido, sin que aparezcan advertencias o cuadros de diálogo emergentes.

¿Es realmente un problema?

Como señalaron algunos comentaristas sobre el descubrimiento de Perry, explotar este error generalmente significa alterar el archivo PAC oficial del proxy de una red privada para incluir JavaScript con trampa explosiva.

Pero si ya tienes el poder de alterar la configuración del proxy de una organización, entonces simplemente puedes redirigir a todos en la red a un proxy falso de todos modos, con o sin errores de JavaScript en la ecuación y si puedes redirigir silenciosamente todos los navegadores de la red, ¿seguramente ya tienes control más que suficiente para causar estragos en la organización?

Por lo tanto, algunos comentaristas argumentaron que CVE-2021-23406 es poco más que una tormenta en una taza de té.

Excepto que redirigir los navegadores de todos a través de un proxy falso, por muy arriesgado que esto pueda ser, simplemente no es tan peligroso como tener la capacidad de ejecutar un programa arbitrario en cada ordenador de la red como efecto secundario de la configuración del proxy sin modificar la configuración del proxy original, de modo que todo lo demás parece seguir funcionando como de costumbre.

Hackear una red reconfigurando abiertamente cada ordenador para comenzar a usar un servidor proxy diferente es mucho más probable que produzca efectos secundarios problemáticos que serán notados, reportados e investigados.

A los ciberdelincuentes contemporáneos les gusta permanecer “fuera del radar” evitando los cambios que los usuarios habituales podrían notar incluso si no estuvieran atentos a los incidentes de ciberseguridad.

¿Qué hacer?

  • ¿Tienes algún software Node.js que utilice Pac-Resolve, Pac-Proxy-Agent o Proxy-Agent? Si es así, asegúrate de tener la versión 5.0.0 o posterior de estos paquetes.
  • ¿Revisas con regularidad los módulos de Node.js en los que se basan tus productos? Si no es así, planea hacerlo. Esto significa tener en cuenta el tiempo extra y la experiencia en el proceso de lanzamiento de tu software. Moverse rápido y romper cosas puede ser un lema útil para prototipos y experimentos internos, pero es una forma imprudente de crear productos finales.
  • ¿Exploras las limitaciones de seguridad de las bibliotecas que usas? Si no es así, debes hacerlo. La creación de una nueva instancia de VM de JavaScript parece que debería mejorar la seguridad, porque cada “máquina virtual” se ejecuta por separado, pero eso no es lo mismo que ejecutarse en una zona de pruebas con control de seguridad o en un jardín amurallado, y la documentación lo dice claramente.
  • ¿Asumes que los paquetes de uso generalizado pueden tratarse como seguros? Si es así, no lo hagas. CVE-2021-23406 no es el tipo de error que probablemente aparezca con el uso regular, a diferencia de un desbordamiento de búfer que puede revelarse a través de bloqueos inesperados. Algunos errores solo se encuentran porque alguien decidió echar un vistazo con cuidado, como lo hizo Tim Perry aquí.

Perry señala que los paquetes de esta historia se descargan alrededor de 3.000.000 de veces a la semana, por lo que la popularidad por sí sola no es garantía de que sean correctos.

Cuando se trata de los llamados errores de la cadena de suministro de este tipo, nunca olvides que puedes subcontratar la codificación, pero no puede subcontratar la responsabilidad.

Dejar un comentario

Your email address will not be published.