Stop compromised npm packages the moment they act.
Static scanners catch what they have already seen. Kratex enforces what every package can do, every time it runs, including the ones nobody has flagged yet.
$ npm i -g @kratex/clinpm packages run code you did not write. Kratex applies your rules to each operation that code attempts.
Stop trusting lifecycle scripts.
Postinstall scripts run with the same access your shell has. kratex install puts them under your rules instead.
$ kratex install
resolving 412 packages
ok react@19.0.0
ok react-dom@19.0.0
block metrics-agent@1.4.2
reason: postinstall.sh requested network
policy: acme / web / v17
ok vite@7.0.0
install incomplete (1 blocked)Apply the same rules at runtime.
Importing a package runs its code with the access your application has. Kratex intercepts its file, network, and spawn operations under the rules that gated the install.
[runtime] import · analytics-sdk@4.2.0
block file read ~/.npmrc
block file read ~/.aws/credentials
block file read ~/.ssh/id_ed25519
block network request 45.61.169.42:443
package blocked · 3 reads, 1 connect, 180ms
rule: acme.block-credential-exfilThe chain is already assembled.
Each event records the device, the package, the full chain of behavior, and the rule that stopped it. No reconstruction.
- block file read ~/.npmrc
- block file read ~/.aws/credentials
- block file read ~/.ssh/id_ed25519
- block network request 45.61.169.42:443
- block postinstall script spawned a subprocess
- block network request telemetry.example:443
Each of these ran on machines that never imported it directly.
- node-ipc (again)
Maintainer's email domain expired. An attacker bought the lapsed domain, used a forgotten-password flow to take over the npm account, and published versions that exfiltrated AWS tokens, SSH keys, Kubernetes configs, and CI secrets to an attacker-controlled server. node-ipc carried millions of weekly downloads at the time.
- @tanstack/*
A fork pull request reached a GitHub Actions runner. The worm's successor, Mini Shai-Hulud, poisoned the CI cache, extracted the publishing OIDC token from runner memory, and shipped 84 malicious versions across 42 @tanstack/* packages in six minutes. By end of day the same campaign had reached 170+ packages across npm and PyPI.
- @bitwarden/cli
TeamPCP, pivoting from the Trivy compromise, pushed a malicious release to the Bitwarden npm namespace. Version 2026.4.0 ran a preinstall that downloaded the Bun runtime, executed an obfuscated loader, and exfiltrated npm tokens, GitHub tokens, SSH keys, and AWS, Azure, and GCP credentials. The stolen data was AES-encrypted and pushed as public repositories under each victim's own GitHub account.
- axios
A North Korean operator phished the lead maintainer and planted a RAT on the maintainer's workstation. Versions 1.14.1 and 0.30.4 added a malicious dependency, plain-crypto-js, that dropped a cross-platform RAT on macOS, Windows, and Linux. Roughly six hundred thousand installs occurred during the three-hour window before the versions were pulled.
- @aquasecurity/trivy-action, 47+ npm packages
An autonomous bot exploited a pull_request_target misconfiguration in Trivy's GitHub Actions workflows. The operator stole a personal access token, force-pushed seventy-six of seventy-seven Trivy action tags to malicious commits, and shipped a poisoned Trivy binary through official channels. Stolen credentials cascaded into the CanisterWorm campaign, which infected 47+ npm packages with a postinstall that stole tokens and republished onward.
- @crowdstrike/*
The same Shai-Hulud worm reached the crowdstrike-publisher npm account. Multiple CrowdStrike-namespace packages, including @crowdstrike/commitlint and @crowdstrike/falcon-shoelace, were republished with a loader that ran TruffleHog against the host and uploaded any matching secrets. CrowdStrike rotated keys and confirmed the Falcon sensor was unaffected.
You can't audit every npm package. With Kratex, you don't have to.
$ npm i -g @kratex/cli