Feed
HighPublished 22 May 2026Updated 26 May 20268 packages · 0 versions

Packagist cross-ecosystem postinstall attack — 8 Composer packages drop Linux `gvfsd-network` binary

Summary

Socket disclosed on 2026-05-23 a coordinated campaign that planted a malicious postinstall hook in the package.json (NOT composer.json) of eight Packagist Composer packages — including devdojo/wave, devdojo/genesis, and katanaui/katana. The hook curls a Linux binary gvfsd-network from github.com/parikhpreyash4/systemd-network-helper-aa5c751f, writes it to /tmp/.sshd, and runs it backgrounded. Socket flagged the same payload in 700+ public GitHub repos.

ci-cd-compromisemaintainer-takeoverobfuscationcdn-supply-chain
Detected by
Socket
Ecosystems
Packagist
Packages tracked
8

What happened

On 2026-05-22 Socket's scanners flagged a coordinated supply-chain campaign that planted an identical malicious postinstall hook in the package.json of eight Packagist Composer packages. The payload was disclosed publicly on 2026-05-23 and amplified by The Hacker News, GuardianMSSP and several syndicated outlets the same day. The standout characteristic is cross-ecosystem placement: every affected package is a Composer/PHP project, but the malicious code lives in package.json rather than composer.json. PHP security teams and Composer-aware scanners do not typically inspect npm lifecycle scripts bundled inside a PHP repo, so the attack rides through unmodified.

The postinstall hook runs a single shell pipeline: it curl -k's the binary gvfsd-network from github.com/parikhpreyash4/systemd-network-helper-aa5c751f (a GitHub Releases URL), writes it to /tmp/.sshd, chmods it executable, and starts it backgrounded. The use of -k disables TLS certificate verification; stderr is suppressed and execution is detached so a failed download never breaks the install. The binary name gvfsd-network masquerades as the GNOME Virtual File System network daemon to blend into a normal Linux process list.

The eight confirmed affected Composer packages, all with malicious commits on dev-branch refs (not on tagged releases), are:

  • devdojo/wave (dev-main) — Laravel SaaS starter, ~1K installs
  • devdojo/genesis (dev-main) — devdojo project
  • katanaui/katana (dev-main) — Tony Lea / devdojo UI kit
  • crosiersource/crosierlib-base (dev-master) — Crosier base library
  • moritz-sauer-13/silverstripe-cms-theme (dev-master) — SilverStripe CMS theme
  • elitedevsquad/sidecar-laravel (3.x-dev) — Sidecar Laravel integration
  • r2luna/brain (dev-main)
  • baskarcm/tzi-chat-ui (dev-main)

Three of the eight (devdojo/wave, devdojo/genesis, katanaui/katana) share the maintainer email tony.woop@devdojo.com, strongly suggesting at least one compromised GitHub account is the common pivot. The other five span unrelated organisations — Socket's working hypothesis is that several maintainer accounts were independently breached by the same operator, plausibly via credential reuse or infostealer harvests.

  • A GitHub code search for parikhpreyash4 returned hundreds of public hits within roughly 17 hours of detection, and Socket extended its scan to 700+ public GitHub repositories carrying the same postinstall-into-/tmp/.sshd fingerprint — including many Node.js projects unrelated to the eight Packagist packages. The Packagist 8 are the confirmed registry-published surface; the GitHub 700+ are public repos that any clone-then-install workflow would also hit.
  • Packagist removed the malicious commits and the affected branches have since been cleaned up; the maintainer-side incident response is ongoing as of disclosure.
  • The malicious code was never present on tagged releases of any of the 8 packages — anyone pinned to a tagged version (^1.0, ~2.5, etc.) was not exposed. Exposure was limited to consumers resolving the affected dev-branch refs.
  • Attribution is open: the parikhpreyash4 GitHub account is single-use throwaway infrastructure and the payload is a generic ELF dropper rather than the Mini Shai-Hulud / TeamPCP credential stealer pattern seen elsewhere this week. No vendor has tied this to a named actor as of disclosure.

Mechanically, this is the cross-ecosystem hook attack class. Adopt npm-aware scanning on PHP repos that ship JS build tooling, pin away from dev-* Composer constraints for third-party packages, and treat package-level postinstall hooks as a high-risk supply-chain surface regardless of the host language.

Affected packages (8)

  • Packagistbaskarcm/tzi-chat-ui
  • Packagistcrosiersource/crosierlib-base
  • Packagistdevdojo/genesis
  • Packagistdevdojo/wave
  • Packagistelitedevsquad/sidecar-laravel
  • Packagistkatanaui/katana
  • Packagistmoritz-sauer-13/silverstripe-cms-theme
  • Packagistr2luna/brain

Impact

  • Remote code execution on any Linux host (developer or CI runner) that runs npm install / yarn install against an affected package — the hook fires from package.json, not composer.json, so Composer-only scanners miss it entirely
  • Cross-ecosystem evasion: PHP / Composer security tooling does not look at package.json lifecycle hooks; npm tooling does not scan PHP repos
  • Persistent Linux backdoor dropped at /tmp/.sshd (named gvfsd-network to masquerade as a GNOME GVfs daemon)
  • curl -k disables TLS verification, hiding the download from cert-pinning egress controls; stderr is suppressed and the binary backgrounded to avoid breaking the install
  • Same payload found in 700+ public GitHub repos, including many Node.js projects — exposure extends far beyond the 8 confirmed Packagist names
  • The malicious commits landed on dev-branch refs (dev-main, dev-master, 3.x-dev) — anyone resolving dev-* Composer constraints pulled the payload

What to do

  1. 1Audit composer.lock / composer.json for any of these 8 vendor names: devdojo/wave, devdojo/genesis, katanaui/katana, crosiersource/crosierlib-base, moritz-sauer-13/silverstripe-cms-theme, elitedevsquad/sidecar-laravel, r2luna/brain, baskarcm/tzi-chat-ui
  2. 2On any host or CI runner that ran npm install (transitively or directly) against an affected package since 2026-05-22: assume Linux compromise. Look for /tmp/.sshd, recently-started background processes named gvfsd-network, and outbound connections initiated from /tmp/.sshd
  3. 3Block egress to github.com/parikhpreyash4/* release URLs from CI/CD and production network paths until GitHub takes the account down
  4. 4Grep your dependency trees and CI workspaces for the literal install command curl -k piping to /tmp/.sshd — Socket reports the same fingerprint in 700+ public GitHub repos beyond the confirmed Packagist names
  5. 5Pin Composer dev-branch dependencies to known-clean commit SHAs predating 2026-05-22, or move off dev-branch constraints altogether — branch refs are mutable and re-resolve on every composer update
  6. 6If you ship JavaScript build tooling alongside PHP, run npm-aware scanners on the same repo — Composer-only tooling will not catch hooks planted in package.json

References

packagist-2026-05-22-cross-ecosystem-postinstall-binary