Mini Shai-Hulud: The Cross-Ecosystem Supply Chain Worm That Jumped From npm to PHP in 14 Minutes

What if the malware infecting your Node.js project could silently leap into your PHP backend — and you wouldn't even notice because the version number never changed?

That's exactly what happened on April 30, 2026, when the "Mini Shai-Hulud" supply chain campaign pulled off one of the most technically impressive — and dangerous — cross-ecosystem attacks the open-source world has ever seen.


The 14-Minute Window

At 20:51:09 UTC, attackers force-updated the Git tag for intercom/intercom-php@5.0.2 to point to a malicious commit. Two minutes later, at 20:53:12 UTC, they swapped it again to a different malicious commit. Fourteen minutes after the first change, Socket's AI scanner flagged the artifact as known malware. Packagist removed it shortly after.

But here's the kicker: the version number never changed. Packagist mirrors Git tags, and Git tags can be force-updated. So 5.0.2 looked identical to developers — same version, same package — but the code inside had been replaced with a credential-stealing worm.

With roughly 700 daily installs targeting that specific version, the malicious artifact had a direct line into high-value developer machines and CI/CD pipelines.


How It Works: Composer Plugin Abuse

The attack didn't rely on developers importing the package in their code. It didn't even need the application to run. The malware triggered during composer install or composer update — before any PHP code was ever executed.

Here's the chain:

1. Malicious composer.json reclassified the package as a composer-plugin and registered Intercom\ComposerPlugin as the entry point 2. Plugin hooks subscribed to post-install-cmd and post-update-cmd 3. Shell script executionsetup-intercom.sh downloads Bun 1.3.13 from GitHub Releases 4. Payload delivery — the 11.7 MB obfuscated router_runtime.js executes

This mirrors the npm attack pattern almost exactly. The only difference? Instead of npm's preinstall hook, the PHP version used Composer's plugin API. Same malware, new delivery vehicle.


The Harvest: What Gets Stolen

Static analysis of router_runtime.js reveals a comprehensive credential and secrets harvester targeting:

- Identity & VCS tokens: GitHub CLI tokens, npm tokens, Git credentials, SSH private keys - Cloud platforms: AWS credentials (IAM, SSM, Secrets Manager, STS), Azure credentials and Key Vault, GCP credentials and Secret Manager - Container & orchestration: Docker credentials, Kubernetes config, service account tokens - Secrets management: HashiCorp Vault tokens - Application secrets: .env files, .npmrc, .pypirc, shell history, wp-config.php

Stolen data is encrypted using AES-256-GCM, with the AES key wrapped using RSA-OAEP/SHA-256, then exfiltrated to https://zero[.]masscan[.]cloud:443/v1/telemetry.

If direct exfiltration fails? The malware falls back to GitHub-based exfiltration using any stolen GitHub tokens, creating repositories with the chilling description: "A Mini Shai-Hulud has Appeared."


Self-Propagation: The Worm That Writes Its Own Payload

This is where Mini Shai-Hulud graduates from "malicious package" to "self-propagating worm."

Using stolen npm tokens, the malware can silently modify and republish npm packages, injecting install-time scripts. It writes payload files into repository paths that blend into normal developer tooling:

- .claude/router_runtime.js - .claude/setup.mjs - .vscode/setup.mjs - .vscode/tasks.json

Commit messages are designed to evade detection: chore: update dependencies, paired with spoofed author metadata like claude .

This isn't just credential theft. This is supply chain worm architecture — using stolen credentials to reach more repositories and packages, propagating through trusted developer workflows.


The Cross-Ecosystem Chain: PyPI → npm → Packagist

The most alarming aspect isn't just the PHP compromise — it's how the attackers bridged three entirely separate package ecosystems.

According to Intercom's confirmation to Socket, the root cause was a local install of pyannote-audio, which introduced the compromised lightning package (PyPI versions 2.6.2 and 2.6.3) as a transitive dependency. That PyPI compromise led to the npm intercom-client@7.0.4 compromise, which then enabled the Packagist artifact for intercom/intercom-php@5.0.2.

One compromise. Three ecosystems. Hundreds of thousands of potential victims.

Why This Matters: The Immutable Myth Is Dead

For years, developers have trusted that version numbers mean something — that 5.0.2 today is the same 5.0.2 as yesterday. Mini Shai-Hulud exposed the structural vulnerability in how PHP's dependency ecosystem handles package integrity.

Packagist's mutable tag system, where Git tags can be force-updated without changing version numbers, is a design choice that just enabled a cross-ecosystem attack. And this isn't just a PHP problem — any ecosystem that mirrors mutable Git tags is potentially vulnerable.


Indicators of Compromise

Security teams should hunt for these artifacts across developer machines and CI/CD runners:

| Indicator | Value | |-----------|-------| | Package hash (zip) | 66664a49edbcee0ed0d8365839707916e92d3aa06e7f26f33c9dcc58e5fc1ef3 | | router_runtime.js SHA256 | 50212a875643520353df158196b9b3be4595094125ad8d2d2c48bdd9cb04ce1f | | C2 endpoint | zero[.]masscan[.]cloud:443/v1/telemetry | | Suspicious string | Running Intercom setup script... | | Propagation marker | A Mini Shai-Hulud has Appeared | | Suspicious paths | .claude/router_runtime.js, .vscode/setup.mjs | | Lock file artifact | /tmp/tmp.987654321.lock |


What You Should Do Right Now

1. Audit all environments for intercom/intercom-php@5.0.2 via composer show or Composer lock file review 2. Check Composer logs for execution of setup-intercom.sh or strings like Running Intercom setup script 3. Remove the malicious artifact and reinstall from a verified, known-good source 4. Rotate ALL exposed credentials — prioritize GitHub tokens, npm tokens, SSH keys, AWS/Azure/GCP credentials, Kubernetes tokens, Vault tokens, Docker credentials 5. Audit GitHub repositories for unauthorized commits, new .github/workflows/ files, .claude/ or .vscode/ payload files 6. Review npm packages controlled by affected maintainers for unauthorized publish events or injected preinstall scripts


The Bigger Picture

Mini Shai-Hulud's expansion into Packagist marks a critical evolution in supply chain attacks. This threat actor is no longer constrained to a single ecosystem. The confirmed compromises across PyPI, npm, and Packagist in a single coordinated chain demonstrate a mature operational model capable of exploiting ecosystem trust boundaries.

Security teams should treat this as a signal: supply chain attacks will increasingly target multi-ecosystem environments simultaneously, leveraging transitive dependencies to bridge between package managers.

The question isn't whether your next supply chain compromise will jump ecosystems. It's whether you'll notice before your credentials are starring in their own GitHub repository called "A Mini Shai-Hulud has Appeared."


Sources:

- Socket.dev Research — Mini Shai-Hulud Spreads to Packagist - The Cyber Defense — Intercom PHP Package Supply Chain Attack - The Register — Supply Chain Attacks Worm Into SAP npm Packages - Sophos — 'Mini Shai-Hulud' Supply Chain Attack Targets SAP npm Packages


Want to test your friends' cybersecurity awareness? Try our Hacker Typer or Fake System Update pranks — 100% harmless, maximum panic.