Skip to content

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/cli
How it works
Install and runtime

npm packages run code you did not write. Kratex applies your rules to each operation that code attempts.

01

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)
02

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-exfil
03

The chain is already assembled.

Each event records the device, the package, the full chain of behavior, and the rule that stopped it. No reconstruction.

runtime · analytics-sdk@4.2.014:42:08
  1. block file read ~/.npmrc
  2. block file read ~/.aws/credentials
  3. block file read ~/.ssh/id_ed25519
  4. block network request 45.61.169.42:443
package blocked · 3 file reads, 1 network request, 180ms · kira-mbp
install · metrics-agent@1.4.214:39:12
  1. block postinstall script spawned a subprocess
  2. block network request telemetry.example:443
install incomplete · 1 package blocked · ci-runner-7
36 compromises since 2017

Each of these ran on machines that never imported it directly.

2026
  1. 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.

  2. @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.

  3. @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.

  4. 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.

  5. @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.

2025
  1. @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