Get a Demo
Under Attack?
Shai-Hulud Strikes Again: intercom-client@7.0.4
Shai-Hulud Strikes Again: [email protected]

[email protected] Supply Chain Attack Enables Credential Theft: Shai-Hulud Strikes Again

<br />
<b>Warning</b>:  Undefined variable $photo in <b>/nas/content/live/landing173/wp-content/themes/bricks/includes/elements/code.php(236) : eval()'d code</b> on line <b>24</b><br />
<br />
<b>Warning</b>:  Trying to access array offset on value of type null in <b>/nas/content/live/landing173/wp-content/themes/bricks/includes/elements/code.php(236) : eval()'d code</b> on line <b>24</b><br />
Amit Genkin April 30, 2026

Executive Summary

[email protected] is a compromised npm package used in a supply chain attack to steal GitHub, npm, and multi-cloud credentials. The malicious version introduces a preinstall hook that executes an obfuscated payload, harvesting secrets and exfiltrating them via GitHub APIs. This activity is part of the Shai-Hulud worm campaign targeting CI/CD pipelines.

Detection Summary

Earlier today, our security team detected a compromise in intercom-client – the official Node.js SDK for Intercom’s customer messaging platform, with over 361,000 weekly downloads. Version 7.0.4, published this morning, had been tampered with and turned into a multi-cloud credential stealer. Despite the package’s massive reach, none of Upwind’s customers downloaded the malicious version.

Upwind detected the threat approximately ~20 minutes after it was published – before it could reach any customer environment. That speed wasn’t luck. Upwind’s detection was powered by an internal scanning engine developed in-house – a purpose-built system that continuously monitors newly published npm package versions for supply chain tampering and malicious code, allowing us to identify the threat independently and ahead of the broader community.

This post is our account of what we found, why it matters beyond this single package, and what teams should do about it.

image-26-1024x520

Background: A Worm, Not an Accident

This compromise did not happen in isolation. It is the third known victim of a coordinated supply chain worm campaign, tracked internally by the security community as Shai-Hulud, that has been propagating through CI/CD infrastructure since at least late 2025.

The mechanics are straightforward and brutal: the worm steals npm publish tokens and GitHub OIDC credentials from infected CI/CD pipelines, then uses them to publish poisoned versions of other packages that those pipelines have publish rights to. Each new victim becomes a propagation vector.

[email protected] was published on April 30, 2026, at 14:41 UTC. The publisher identity in the npm registry shows [email protected] – a GitHub Actions OIDC token. The Intercom engineering team did not publish this version. Their CI/CD pipeline was used against them.

What’s Inside 7.0.4

The malicious version is almost indistinguishable from 7.0.3 at the surface. The legitimate SDK code is intact. The package works exactly as expected. That’s by design.

What changed:

package.json gained a single new line:

"preinstall": "node setup.mjs"

Two new files appeared that have no history in the package’s GitHub repository:

  • setup.mjs – 6,780 bytes, 222 lines
  • router_runtime.js – 11,731,860 bytes, a single obfuscated line

The unpacked size jumped from 6 MB to 17.8 MB. SLSA provenance attestations, present in 7.0.3, are absent entirely.

The Loader – setup.mjs 

The preinstall hook executes setup.mjs, which only acquires the Bun JavaScript runtime and uses it to run router_runtime.js. Bun is downloaded directly from GitHub releases, a trusted domain. If Bun is already installed on the system, it reuses the existing installation.

The choice of Bun over Node.js is deliberate: most EDR and SIEM detection rules that flag suspicious subprocess activity during npm install are tuned for node child processes. A bun process flies entirely under that radar.

The loader correctly handles Alpine/musl environments, includes a pure-Node ZIP parser fallback for minimal container images, and cleans up after itself – deleting the downloaded zip and Bun binary on exit to reduce forensic footprint.

The Payload – router_runtime.js

This is the credential harvester. At 11.7 MB with zero newlines, it is a single obfuscated line encoding a full multi-cloud credential sweep:

  • GitHub tokens – Personal access tokens (ghp_*), OAuth tokens (gho_*), and Actions/OIDC tokens (ghs_*)
  • npm tokens – Publish access tokens matching npm_[A-Za-z0-9]{36,}. Stolen tokens are what enable worm propagation.
  • AWS credentials – Queries the Instance Metadata Service at http://169.254.169.254 for role credentials. Also scans environment variables and config files for aws_secret_access_key, aws_session_token, and access key ID patterns (AKIA[A-Z0-9]{16}).
  • GCP credentials – Queries http://metadata.google.internal for service account tokens. Scans for Application Default Credentials JSON files.
  • Azure credentials – Scans for storage connection strings, client secrets, and access keys matching patterns like AccountKey, accessKey, and client_secret.
  • Private keys and generic secrets – PEM-encoded RSA and ECDSA keys, and broad pattern matching on variables named password, secret, token, api_key, and similar.

The payload also detects CI/CD environments specifically and activates targeted collection behavior, including GitHub Actions, Vercel, and generic CI environments.

Exfiltration

Nothing goes to an unknown command-and-control domain. Everything goes to api.github.com.

Using the stolen GitHub token, the payload authenticates, creates a private repository under the victim’s account, and commits the harvested credentials there. From a network monitoring perspective, this is indistinguishable from a developer pushing code. The domain is trusted. The traffic is HTTPS. Standard egress controls, domain blocklists, and IP-based detection are useless here.

What We Observed at Upwind

Upwind flagged [email protected] as malicious roughly 20 minutes after it was published – well before it could propagate through customer pipelines. Around 15% of our customers have an intercom-client in their dependency tree. None of them installed the malicious version.

What surfaced wasn’t a CVE match or a known-bad hash. It was behavioral. Three risk patterns fired simultaneously:

  • A preinstall hook appeared for the first time in a package that had never used one across its entire version history. an immediate anomaly signal.
  • Two undocumented files were injected (setup.mjs and router_runtime.js) with no corresponding commits in the upstream GitHub repository. The package size tripled in a single patch bump.
  • SLSA provenance attestations were absent. Version 7.0.3 carried them. 7.0.4 did not. means this publish did not come from the legitimate Intercom CI workflow that generates them.

None of these signals would have surfaced through traditional vulnerability scanning. This is exactly the kind of attack that slips through when detection relies on known signatures rather than behavioral baselines.

What To Do Now

  • Check if you’re affected: Search your dependency tree and lockfiles for [email protected]. Also look for the two malicious files – setup.mjs and router_runtime.js – inside the package’s node_modules directory. Either finding confirms a compromised install.
  • Downgrade and reinstall cleanly: Remove 7.0.4 and explicitly pin to 7.0.3. When reinstalling, use the --ignore-scripts flag to prevent any lifecycle hooks from executing.
  • Rotate all credentials that were in scope: Any GitHub tokens, npm publish tokens, or cloud credentials (AWS, GCP, Azure) accessible to a pipeline that ran this install should be treated as compromised and rotated immediately – don’t wait to confirm exfiltration.

Attacks Aren’t Slowing Down 

This isn’t a one-off incident. Over the past 12 months, we’ve seen a steady and accelerating rise in supply chain attacks targeting npm, PyPI, and other package ecosystems. What’s changed isn’t just the frequency – it’s the sophistication. Attackers are no longer uploading obvious typosquats. They’re compromising legitimate maintainer accounts, hijacking CI/CD pipelines, and publishing malicious versions under trusted identities. The package looks right. The publisher looks right. The version bump looks routine.

Shai-Hulud is a particularly sharp example of where this threat is headed: a self-replicating worm that uses each victim’s infrastructure to find and infect the next target, expanding its credential harvest with each generation. Today, it’s AWS, GCP, and Azure tokens. Tomorrow, it’s whatever sits in your pipeline environment.

At Upwind, supply chain threat detection is built into our monitoring of cloud-native environments. We watch for anomalous package behavior at install time, correlate it against runtime activity across CI/CD pipelines and cloud workloads, and surface signals early. As today’s 20-minute detection demonstrates. If you’re running Node.js services in AWS, GCP, or Azure and want to understand your exposure to this class of attack, we’d like to talk.

Contents

Further Reading

Agent Scanner

Announcing the Upwind AI Context Scanner – Securing AI Agents’ Instructions, Skills and Model Context

AI agents are spreading across enterprise operations, from local coding tools on employee endpoints, to agents operating infrastructure or processing sensitive customer data, to fully autonomous cloud workflows. Agents operate with human credentials and gain real system access, and introduce a brand-new attack surface. To secure an AI agent, you have to look deep in…
AI-DR-Hero (1)

Upwind AI DR is Generally Available: metaCatch Compromised AI Agents in Real Time

We're excited to announce that Upwind AI DR (AI Detection & Response) is now generally available. AI DR gives security teams real-time detection and response for the AI agents running in production, not by bolting on a new sensor, but by extending the runtime intelligence Upwind already has. The Upwind Cloud & AI Security Platform…
Focus-Mode

Focus Mode for AI Security: A Dedicated Workspace for Identifying and Securing Your AI Stack 

When we launched Focus Mode, we built it around the way security teams actually work: Vulnerability Management, Cloud Security Posture, Attack Surface Management, Threat Detection & Response, Administration. Each one strips away everything unrelated to the job at hand. AI Security is the next domain in the Focus Mode lineup, and it's built for a…
Add the Upwind RSS Feed to Slack
Connect the Upwind RSS Feed to your Slack.
Follow the how-to here.
Threat RSS
Add the Upwind RSS Feed to Slack
Connect the Upwind RSS Feed to your Slack.
Follow the how-to here.
Main RSS