“A Mini Shai-Hulud Has Appeared”: When the npm Supply Chain Reaches Into SAP
Chapters
Share Article
Let's Talk SAP Security
Have questions about SAP Security? We’re here to help. Contact Us
On 29 April 2026, four official npm packages from the SAP development ecosystem were published in malicious versions. For roughly two to four hours that day, anyone running npm install against the wrong version pulled a credential-stealing payload straight into their developer workstation or CI/CD pipeline. The campaign, which researchers are calling “Mini Shai-Hulud”, marks the first time the Shai-Hulud worm family has reached directly into the SAP supply chain and it is a signal worth paying attention to.
What was compromised
Four packages were poisoned with malicious versions:
- @cap-js/sqlite v2.2.2
- @cap-js/postgres v2.2.2
- @cap-js/db-service v2.10.1
- mbt v1.2.48
These are not obscure dependencies. The @cap-js/* packages are core building blocks of the SAP Cloud Application Programming Model (CAP), the de-facto framework for almost any custom development on SAP BTP. mbt is the Cloud MTA Build Tool, used in CI/CD pipelines that build and deploy Multi-Target Applications to SAP BTP and on-premises systems. Together, the four packages account for roughly 570,000 weekly downloads.
SAP detected the compromise quickly and superseded the affected versions with clean releases the same afternoon. SAP has since published Security Note 3747787 (“Malicious open-source packages in SAP Cloud Application Programming Model & MTA Build Tool”) with the official list of indicators of compromise, file hashes, and mitigation steps. Customers should consult the note directly through SAP for Me. What follows is a summary, not a substitute.
How the attack worked
The compromised packages still contained the legitimate SAP source code, byte-for-byte. The malicious behavior was tucked into three injected files: a modified package.json, a new setup.mjs, and a new execution.js.
The mechanics are worth understanding because they were deliberately built to evade conventional Node.js-focused tooling:
- A preinstall hook in package.json runs setup.mjs automatically on install, before any application code executes.
- setup.mjs downloads the Bun JavaScript runtime from GitHub Releases. Bun is then used instead of Node.js to run the second stage. Static analysis and Node.js-centric runtime monitoring largely don’t see this.
- execution.js; an obfuscated ~11 MB payload, harvests GitHub tokens, npm credentials, AWS/Azure/GCP secrets, Kubernetes config, SSH keys, .npmrc and .git-credentials files, and CI/CD environment variables.
- Stolen data is encrypted (AES-256-GCM, wrapped with RSA-4096) and exfiltrated by creating a public GitHub repository on the victim’s own account, tagged with the description “A Mini Shai-Hulud has Appeared”. Within hours, more than a thousand such repositories were visible to a public GitHub search.
- With any stolen npm token, the payload can republish itself into other packages the maintainer has access to, a worm by design.
Figure 1: A live GitHub search for the attacker’s signature description string surfaces over a thousand victim repositories within hours of the attack, each one a developer whose credentials were stolen by an npm install.
The initial publishing-pipeline compromise appears to have hit a maintainer account on the cap-js/cds-dbs side and an automation token (cloudmtabot) on the mbt side. A misconfigured npm OIDC trusted-publisher rule, trusting the entire repository instead of a single workflow on a protected branch, is what made the OIDC route exploitable. SAP also lists the GitHub commit author claude <[email protected]> among the indicators of compromise, suggesting the attacker leveraged a developer’s Claude Code GitHub integration to push the malicious workflow. The activity overlaps in tooling, region guard-rails, and infrastructure with prior TeamPCP supply-chain operations.
Why this matters more for SAP customers
Most npm supply-chain attacks land on developer laptops or generic web pipelines. This one lands on SAP-specific build environments, and that changes the blast radius:
- mbt runs where production SAP credentials live. MTA build pipelines typically hold deployment credentials for SAP BTP subaccounts, Cloud Foundry orgs, transport routes, and sometimes service keys for HANA, Destination service, or XSUAA. A stolen build-time token is, in practice, a foothold into a productive SAP landscape.
- CAP is the mainstream framework for custom BTP development. A successful preinstall on a CAP developer’s machine yields not only cloud secrets but also access to source repositories where business logic for ERP-adjacent systems lives.
- SAP organizations are not uniformly mature on Node.js/npm hygiene. SAP shops have decades of muscle memory for ABAP transports and patch days. Lockfile review, provenance attestation, ephemeral build runners, and dependency pinning are still uneven across the ecosystem.
In other words: this is the first credential-stealing worm to specifically target the JavaScript layer of SAP, and it landed on exactly the tooling that touches productive systems.
What to do now
If your organization has anything to do with SAP CAP or MTA pipelines, treat this as an active incident response item, not a curiosity. SAP Note 3747787 gives the authoritative checklist; the practical version reads as follows:
- Hunt for the four bad versions. Search every lockfile, container image, build cache, and artifact repository for @cap-js/[email protected], @cap-js/[email protected], @cap-js/[email protected], and [email protected]. The note also publishes SHA-512 hashes for the malicious execution.js, setup.mjs, and package.json files — use these for forensic confirmation rather than relying on version strings alone.
- Quarantine — and consider re-imaging — affected systems. SAP is explicit on this point: uninstalling or downgrading alone is not sufficient, because the payload can leave persistence behind in IDE configurations and other places that survive a package downgrade.
- Rotate every credential within blast radius. npm tokens, GitHub PATs and OAuth tokens, AWS/Azure/GCP credentials, Kubernetes kubeconfigs, SSH keys, and any CI/CD secrets present on developer machines or runners that touched the bad versions.
- Look for the indicators SAP enumerates. GitHub repositories whose description matches “A Mini Shai-Hulud has Appeared”; commits containing the string “OhNoWhatsGoingOnWithGitHub”; commits authored by claude <[email protected]> or with the message chore: update dependencies (both flagged by SAP as suggestive but not conclusive); unexpected workflow branches; and changes to IDE configurations (e.g. .vscode/tasks.json, .claude/settings.json) that may have been committed into other repositories on affected machines.
- Audit and clean up. Delete unauthorized GitHub repositories (Dune-themed names are a strong signal), remove injected workflow branches, revert IDE-config changes the payload pushed into other repos, and unpublish any unexpected version bumps from npm packages your team owns.
- Pin exact versions. SAP explicitly recommends pinning exact npm versions to prevent silent upgrades to malicious patch releases. Floating ranges (^, ~) are how a two-hour attack window turns into a thousand-victim campaign.
- Harden the publishing path going forward. Scope npm OIDC trusted publishers to a specific workflow file on a protected branch, require provenance, and remove long-lived automation tokens wherever possible.
The takeaway
The attack surface of an SAP system is no longer confined to ABAP, Gateway, RFC, and the kernel. CAP, BTP, MTA, and the npm packages that build them are now part of that surface and they sit in places where a single malicious preinstall can trade developer convenience for production credentials. Mini Shai-Hulud is small in scope. The pattern it establishes is not.
We will continue to track this campaign and update customers accordingly.
