Security researchers at Socket have uncovered a coordinated attack targeting PHP Composer packages by hiding malicious JavaScript lifecycle hooks right under developers’ noses.
According to the official findings:
“Socket researchers identified a coordinated supply chain campaign affecting eight Composer packages whose upstream repositories were modified to include the same malicious postinstall script.”
The Cross-Ecosystem Blind Spot
What makes this campaign highly notable is where the malicious code was planted. Instead of tampering with standard PHP metadata files like composer.json, the threat actor injected a postinstall script into package.json. This specifically targeted repositories that pack JavaScript build tooling alongside their core PHP code.
As Socket points out in their report:
“That cross-ecosystem placement is notable because developers and security teams reviewing PHP dependencies may focus on Composer metadata while overlooking package.json lifecycle hooks bundled inside the package.”
When a developer or CI/CD workflow runs npm install to bundle the frontend assets, the hidden script quietly fires in the background.
Dissecting the Stealth Payload
The malicious postinstall script behaves like a classic backdoor wrapper. It uses curl -skL to bypass TLS certificate verification and fetch a Linux binary called gvfsd-network from an attacker-controlled GitHub Releases URL.
From there, the script writes the binary to a hidden local path (/tmp/.sshd), intentionally named to mimic a legitimate SSH daemon. It then silences error outputs using 2>/dev/null, marks the binary as executable, and boots it up as a background process.
The attack surface isn’t confined to just local installations, either. Researchers observed the exact same payload embedded inside GitHub Actions workflow files (.github/workflows/ci.yml) disguised as a “Dependency Cache Sync” step, actively poisoning automated build pipelines.
Why Starter Kits Are the Most Vulnerable
While eight branch-tracking package versions were flagged—including configurations for Silverstripe and Laravel extensions—the real-world danger heavily concentrates around open-source starter kits like devdojo/wave and devdojo/genesis.
Socket explains why these projects face the highest risk:
“Starter kits are the worst case for this attack pattern. The repository becomes the developer’s project, so the malicious package.json lands at the project root, where npm install runs its postinstall script directly.”
For typical standard libraries tucked away deep inside a vendor/ folder, a top-level npm install won’t trigger dependency scripts. But with starter kits, the poison sits right at the root of the application.
Defensive Action Items
Fortunately, Packagist moved swiftly to delete the compromised package entries after receiving Socket’s report, and several maintainers have already reverted the rogue commits. However, because this exploit targeted branch-tracking development streams (dev-main, dev-master), there is a lingering risk of re-infection if upstream repositories remain unfixed during future updates.
- Audit Beyond Composer: If your PHP applications bundle JavaScript build workflows, you can no longer afford to only audit
composer.json. Build a routine to inspect bundledpackage.jsonscripts and your active CI/CD workflow configurations. - Verify Commit States: For branch-tracking packages, do not rely purely on the version tag. Pin your environments to specific, verified git commit hashes or immutable archive states to prevent moving targets from pulling down malicious states.
Support Our Threat Intelligence
If you find our CVE report and cybersecurity news helpful, consider supporting our work.