
A breach of an official SAP npm package does not constitute a mere npm threat. It is a concrete case of a corporate toolchain becoming hostile to the corporation through its use of the install command before any application logic runs.
On April 29, 2026, four genuine SAP packages became compromised versions, @cap-js/sqlite 2.2.2, @cap-js/postgres 2.2.2, @cap-js/db-service 2.10.1, and mbt 1.2.48. SAP responded swiftly by creating subsequent CAP packages, an mbt 1.2.49 tag on the same day, and a workflow update with npm publication requiring human approval.
Official Packages Became The Attack Surface
The significance of this attack stems from the fact that the affected packages reside near enterprise application development and deployment activities. In SAP’s own technical documentation, @cap-js/sqlite is leveraged for local CAP development and in-memory testing, @cap-js/postgres offers PostgreSQL capabilities for CAP, @cap-js/db-service is the database engine shared between both packages, and mbt generates the .mtar archive required for deploying SAP applications to the cloud. In essence, these are not esoteric tools; rather, they represent packages bound to be executed on developer machines and CI runners with pre-existing access to the source code, publish permissions, and cloud credentials.
Some specifics have made this vulnerability particularly concerning. For instance, the @cap-js/db-service and @cap-js/sqlite packages have an estimated combined weekly download of several hundred thousand, whereas mbt enjoys steady adoption within enterprise organizations. On the other hand, npm claims over 17 million registered developers using the registry service, and GitHub has exceeded 100 million users for years. Thus, even a highly-targeted exploitation will scale rapidly once embedded within trusted automation processes.
A Tiny Preinstall Hook Opened The Front Door
At first, there was no need for complex exploit chains. Rather, the authors leveraged npm lifecycle logic as intended by design. Malicious packages included a preinstall hook running node setup.mjs during the npm install process. Indeed, according to npm official documentation, scripts in the installation process are executed automatically, whereas preinstall script is rarely needed. This is what made this particular attack very dangerous since it allowed leveraging a feature intended to provide convenience. Besides, a relatively large number of files remained untouched in terms of changes, thus minimizing chances of detection via manual examination.
Technically speaking, this modification was simple yet sophisticated enough. According to public reverse engineering, files found in legitimate packages of at least one sample were identical to those present in the original version of the packages byte for byte, whereas the only new components introduced were package.json, setup.mjs and an extremely large obfuscated file execution.js. In addition, one could say that suspicious modifications were detected based on metadata of certain files. Specifically, new files had April 29 timestamps, whereas all other files had a standard format typical for npm.
The Pictures Reveal The Real Tradecraft
Telemetry from the process shows an especially informative path. One of the runtime telemetry captures python3 accessing /proc/…/mem through the Runner.Worker process running on a GitHub Actions host. This point is crucial, because it proves that the attack was aimed at extracting live memory rather than configuration files from the disk. In other words, even secrets that were redacted from logs could be extracted if the malicious payload was able to access them after they were loaded into RAM by the runner. The process flow diagram also reveals several important points: npm install triggers execution of setup.mjs, which, in its turn, downloads Bun 1.3.13 and then executes the huge payload obfuscated in its code.
On the side of exfiltration, the GitHub search diagram illustrates how the malware worked. The attacker did not use some suspicious domain or service to send out stolen data. Instead, they used their GitHub repositories to host data in repositories with identical descriptions, “A Mini Shai-Hulud has Appeared,” and generic names. That tactic is quite clever in terms of stealth, because GitHub servers are a common target of any network scan and connections to them do not raise suspicions.
The Payload Reached Far Beyond Environment Files
This wasn’t just another narrow token snatcher either. The payload was designed to target tokens for npm, GitHub, SSH keys, credentials from cloud providers, Kubernetes, environment variables, messaging apps, browser credentials, and development tools cache data. Furthermore, it queried metadata endpoints from AWS, Azure, and GCP. In CI, the malware checked the contents of runner memory. On developer machines, the malware gained persistence through .claude/settings.json and .vscode/tasks.json meaning that the mere act of working on an open source project using an AI development application could have caused it to re-spawn the malware. That’s quite a step forward.
From a tradecraft perspective, there were two standout features of the attack. First, the data that the malware collected was encrypted with AES-256-GCM and then the encryption key was wrapped using the embedded RSA public key; only the operator would be able to decrypt the archive of stolen credentials. Second, for C2 communication, it used GitHub commit search functionality as dead drop via OhNoWhatsGoingOnWithGitHub marker. It makes the legitimate public service infrastructure a part of command & control infrastructure.
The Publish Workflow Was The Likely Weak Point
The company’s immediate follow-ups show clearly what the lesson of the whole experience should be. A same-day pull request in CAP database repository highlights how a series of unauthorised commits took control of the release process and led to unauthorised npm publications. Another pull request segregated the process of composing release notes from the process of publishing. The use of such language makes one conclude that the registry was not the place where things started going wrong. What was exploited first was the process of publishing. Once that pipeline became exposed, packages were used to deliver the payload.
Some of the public CI evidence of the mbt incident proves exactly this idea. Build logs of a brief-lived pull request revealed a malicious loader code, an obfuscated payload and access to release-related secrets in the automation pipeline. At the same time, documentation of npm publishing shows how short-lived tokens based on the OIDC authentication method can be used for publishing. It is certainly better than long-lived tokens, but if an attacker manages to execute code within the pipeline, those credentials give him enough power to do the deed.
This Signals A New Phase For Software Supply Chain Attacks
Conventional package attacks would be carried out using typo-squatting, dormant domains, or obvious malware code. However, in this case, the attack made use of legitimate packages, few changes in the files involved, another runtime environment, GitHub storage, memory scraping, and persistence via IDE or AI tools. The attack was reminiscent of the Bitwarden CLI hack carried out in April, which also utilized GitHub as the source for exfiltration as well as installation-time execution.
Conclusion: When Official Toolchains Become Hostile
The SAP CAP incident proves that supply chain risk no longer starts with suspicious packages or obvious impostors. These were official SAP npm packages, trusted by developers and CI/CD systems, modified through the release path, and executed automatically during installation. One small preinstall hook was enough to turn a normal build workflow into a credential theft operation.
Why This Threat Matters
This attack targeted the places where enterprise software is created, tested, and deployed.
- CAP and MTA packages sit directly inside SAP development workflows
- npm install executed setup.mjs before application logic ever ran
- The payload searched developer machines and CI runners for npm tokens, GitHub tokens, SSH keys, cloud credentials, Kubernetes secrets, browser data, and AI tool secrets
- Runtime memory was targeted, meaning secrets hidden from logs could still be exposed once loaded by the runner
Why Developer Teams Stay Exposed
Modern build systems trust automation by default. Package scripts run. CI jobs inherit secrets. Developer tools cache credentials. GitHub traffic looks normal. That is exactly why this attack was so dangerous, it abused ordinary workflows rather than breaking them.
When install equals execution, the software supply chain becomes a runtime attack surface.
Where Xcitium Changes the Outcome
If you have Xcitium Advanced EDR, this attack would NOT succeed the way the attacker needs.
- Malicious preinstall logic is intercepted at execution
- Code can run without being able to cause damage
- Secrets, tokens, and local development assets remain protected from the payload
- Persistence through IDE and AI tool hooks loses the runtime path it depends on
The attacker may compromise the package, but they do not get the execution outcome required to steal credentials or spread downstream.
Secure the Build Path Like Production
The SAP npm compromise shows that official packages can become hostile without looking suspicious. Protect developer workstations, CI runners, and build environments at runtime, because the next supply chain breach may arrive through the tools your teams trust most.