Key Takeaways
- Eight Composer packages on Packagist were compromised with malicious code placed in
package.jsonpostinstall scripts, targeting JavaScript build tooling alongside PHP code. - The attack is notable for its “cross‑ecosystem” placement, allowing it to evade scans that focus only on Composer metadata.
- The malicious script downloads a Linux binary from a GitHub Releases URL, saves it to
/tmp/.sshd, makes it executable, and runs it in the background. - Affected packages include
moritz-sauer-13/silverstripe-cms-theme,crosiersource/crosierlib-base,devdojo/wave,devdojo/genesis,katanaui/katana,elitedevsquad/sidecar-laravel,r2luna/brain, andbaskarcm/tzi-chat-ui(all dev‑main or dev‑master branches, plus a 3.x‑dev variant). - Socket’s analysis found the same payload in 777 GitHub files, including workflow files, suggesting a broader campaign, though the exact number of distinct compromises remains unclear.
- The second‑stage binary’s purpose is unknown because the hosting GitHub account has been removed; the file was named
gvfsd-network, mimicking a GNOME Virtual File System daemon. - Even without the payload, the installer provides remote code execution during installation or build processes and hides its activity by disabling TLS verification, suppressing errors, and running the binary in the background.
Overview of the Coordinated Supply Chain Attack
In May 2026, security researchers at Socket disclosed a coordinated supply chain attack that impacted eight Composer‑hosted packages on Packagist. Although the packages are PHP‑oriented, the malicious code was not inserted into the usual composer.json manifest; instead, it was added to package.json files as a postinstall script. This technique allowed the attackers to execute arbitrary code whenever a developer ran npm install or yarn as part of a project’s JavaScript build tooling, even when the primary language of the package was PHP. The attack demonstrates how threat actors are broadening their focus beyond language‑specific package managers to exploit cross‑language development workflows.
Mechanism of Malicious Insertion via package.json
The core of the intrusion lies in a postinstall hook defined within the compromised package.json files. When a developer installs the package, the script automatically triggers, retrieving a remote binary from a GitHub Releases URL (github[.]com/parikhpreyash4/systemd-network-helper-aa5c751f). The script then writes the binary to a hidden location (/tmp/.sshd), changes its permissions with chmod +x to make it executable for all users, and launches it in the background. Because the hook runs automatically during the installation phase, victims may not notice any anomalous behavior until the binary executes its payload.
Why Cross‑Ecosystem Placement Is Significant
Security teams and automated scanning tools often concentrate on Composer‑specific metadata when auditing PHP dependencies. By placing the malicious code in package.json — a file traditionally associated with Node.js/JavaScript projects — the attackers bypassed many conventional checks that ignore JavaScript‑related lifecycle hooks in PHP packages. This “cross‑ecosystem” approach increases the likelihood that the malicious script will execute undetected, especially in repositories that maintain both PHP backend code and frontend/build tooling managed via npm or yarn.
Detailed Actions of the Malicious Postinstall Script
The script follows a multi‑step process designed to minimize detection while establishing persistence. First, it disables TLS verification for the download command, allowing the binary to be fetched even if certificate checks would normally block it. Second, it suppresses error output, so any failure to retrieve the binary remains invisible to the user. Third, after saving the binary to /tmp/.sshd, it executes chmod 777 /tmp/.sshd to grant read, write, and execute permissions to everyone, ensuring the binary can run regardless of the user’s privilege level. Finally, the script launches the binary with an ampersand (&) to detach it from the parent process, letting it operate stealthily in the background.
List of Affected Packages and Versions
Socket identified the following packages as carrying the malicious postinstall script:
moritz-sauer-13/silverstripe-cms-theme(dev‑master)crosiersource/crosierlib-base(dev‑master)devdojo/wave(dev‑main)devdojo/genesis(dev‑main)katanaui/katana(dev‑main)elitedevsquad/sidecar-laravel(3.x‑dev)r2luna/brain(dev‑main)baskarcm/tzi-chat-ui(dev‑main)
All compromised versions were pre‑release or development branches, which are frequently pulled by developers during active feature work or continuous integration pipelines, thereby increasing the exposure window.
Evidence of a Broader Campaign Across GitHub
Beyond the Packagist packages, Socket’s threat intelligence team discovered identical payloads in 777 files scattered across public GitHub repositories. In at least two cases, the malicious code was embedded directly into GitHub Actions workflow files, meaning it would execute during automated CI/CD jobs triggered by push or pull‑request events. This dual‑vector approach — targeting both package installation hooks and CI workflows — suggests the attacker was experimenting with multiple execution mechanisms to maximize reach. However, due to the prevalence of forks, duplicates, and cached references, it remains difficult to ascertain how many of these instances represent distinct compromises versus mere copies of the same tainted artifact.
Uncertainty Surrounding the Second‑Stage Payload
The ultimate purpose of the downloaded binary remains unclear because the GitHub account that hosted the repository (parikhpreyash4) has since been removed, taking the binary with it. The file was named gvfsd-network, a deliberate allusion to the GNOME Virtual File System daemon that manages network shares, possibly intended to masquerade as a legitimate system component. Socket emphasized that even without observing the second‑stage payload’s behavior, the installer itself constitutes a serious threat: it provides remote code execution during the installation or build process and employs evasion techniques such as disabling TLS verification, muting error messages, and running the binary covertly in the background.
Implications, Mitigation, and Recommendations
This incident underscores the necessity of expanding dependency‑scanning practices beyond language‑specific manifests. Organizations should audit both composer.json and package.json files (or equivalent manifest files) for unexpected scripts, especially postinstall, prepublish, or similar lifecycle hooks. Implementing integrity checks — such as locking dependencies to specific versions or hashes, using tools like npm audit or composer audit with script‑inspection plugins — can help detect unauthorized modifications. Additionally, monitoring outbound network traffic for connections to unfamiliar GitHub Releases URLs and enforcing strict TLS verification can impede the download phase of such attacks. Finally, maintaining an inventory of all third‑party code, including transitive dependencies, and regularly reviewing change logs for suspicious modifications are critical steps to defend against similar supply chain threats.
Conclusion
The coordinated attack on eight Packagist packages illustrates how adversaries are adapting to modern polyglot development environments by injecting malicious code into cross‑ecosystem files like package.json. By exploiting postinstall scripts, they achieve remote code execution during routine dependency installation, conceal their activity, and potentially leverage CI/CD pipelines for broader impact. While the exact nature of the second‑stage payload remains unknown due to the removal of the hosting GitHub account, the installer’s capabilities alone warrant immediate blocking and remediation. Heightened vigilance, comprehensive script auditing, and robust validation of all manifest files are essential to mitigate the risk of future supply chain compromises of this kind.

