Skip to content

0xSteph/patient-zero

Repository files navigation

patient-zero

Scans Node, Python, and AI-agent configs for indicators of compromise from npm and PyPI supply-chain attacks (Sept 2025 – present). Triage in 30 seconds, block malicious installs before postinstall runs, or wire it into your CI — same IoC database, three modes, one command.

npm downloads ci license node telemetry signup runs

$ npx patient-zero

Findings
────────

chalk maintainer phish (Sept 2025)
  ❌ CRITICAL · GHSA-demo-chalk
     Package: chalk@4.0.0 in package-lock.json
     What to do:
       • Run `npm ls chalk` to find which workspace pulls this version
       • Pin to a clean version (chalk@5.0.0+) in package.json and re-install
       • Rotate any tokens that were in env during the install window
     Commands:
       $ npm ls chalk
       $ npm install chalk@5.0.0
     Source: https://security.snyk.io/

Scanned 1 lockfiles · 234 processes · 2 MCP configs · 0 repos · 0 paths checked
0.02s · coverage 2025-09-08 → present · 7 families · 6 indicators · IoC: fresh
Or watch the 12-second animated demo

demo

Three ways to use it

1. On-demand triage — when the news breaks

npx patient-zero@latest

No global install, no signup, no config. Runs against the current directory. Use this when chalk / axios / the latest Shai-Hulud variant hits Hacker News and you need a fast yes/no on whether your machine is affected.

2. Install-time blocking — catch malware before it runs

npx patient-zero@latest install <package>

Resolves the proposed install tree in a sandboxed temp directory, cross-references every transitive dependency against the IoC database, and refuses to proceed if any indicator matches. Postinstall scripts never execute. This is the most valuable single feature for the agent era — your AI agent installs things on your behalf; you don't see every install; this catches it.

3. Continuous CI — every commit, every PR

- uses: 0xSteph/patient-zero@v0.2
  with:
    fail-on: medium

Drops into any GitHub Actions workflow. Produces SARIF that populates GitHub's Security tab automatically. No tokens, no Snyk-style signup, no per-seat pricing.

Or as a pre-commit hook:

npx patient-zero install-hook

Auto-detects husky / lefthook / pre-commit / native git hooks and wires patient-zero into the right place. Idempotent and removable.

What it scans

  • AI-agent MCP configs — Claude Desktop, Claude Code, Cursor, Cline. Known-malicious servers, typosquats of @modelcontextprotocol/*, non-HTTPS URLs, sensitive credentials in env blocks. Nobody else covers this lane.
  • Running processes — matches known malicious daemons (e.g. Shai-Hulud's gh-token-monitor).
  • Local persistence~/Library/LaunchAgents/ (macOS), ~/.config/systemd/user/ (Linux), ~/.npmrc, ~/.pypirc.
  • npm + Python lockfilespackage-lock.json, pnpm-lock.yaml, yarn.lock, requirements.txt, poetry.lock. Semver-aware version matching.
  • Your GitHub account (opt-in) — uses gh CLI or a PAT you provide. Looks for repos created by stolen credentials matching known attack patterns.

See the full IoC list → · Schema → · MCP IoC guide →

What this is NOT

  • Not an EDR or runtime sandbox.
  • Not a replacement for continuous monitoring tools like Snyk or Socket — works alongside them.
  • Not a vulnerability scanner (we scan for known-malicious indicators, not CVEs).

The opinionated bet: most of the value is in not-on-GitHub coverage (MCP configs, processes, local persistence) plus install-time blocking. GitHub's Dependabot now covers part of the lockfile-malware lane natively as of March 2026; we focus on the parts it doesn't.

Covered attacks

Auto-generated from data/iocs.json. To add a new attack family, see CONTRIBUTING.md.

Attack family First observed Ecosystem IoC class Source
Shai-Hulud 2025-09-15 npm package + file + process + github StepSecurity
chalk maintainer phish 2025-09-08 npm package Snyk Advisory
SANDWORM_MODE 2025-11-01 npm package + network Socket
Shai-Hulud 2.0 2025-12-09 npm package + file + process + github Microsoft
axios postinstall 2026-03-12 npm package + network GHSA
Mini Shai-Hulud (TanStack) 2026-05-01 npm package StepSecurity

Tracks 6 named attack campaigns + 1 heuristic family (MCP supply-chain patterns) · 6 indicators · coverage window 2025-09-08 → present. (Auto-updated every hour by the aggregator workflow; the numbers in this line are a static snapshot of v0.2.0.)

Exit codes

For CI use. Same contract across all three modes.

0  Scan completed. Zero IoCs matched at any severity ≥ low. (Install passed through cleanly.)
1  Scan completed. ≥1 IoC matched at severity ≥ medium. (Install was blocked — postinstall did NOT run.)
2  Scanner error (network, parse, permission). Scan did not complete.

If patient-zero flags something

Don't panic, don't revoke tokens yet. Read docs/RESPONSE.md first — it has per-attack-family triage steps.

Critical caveat for Shai-Hulud family findings: the gh-token-monitor daemon has a destructive failsafe. If patient-zero shows a Shai-Hulud finding, read docs/SHAI-HULUD-FAILSAFE.md before rotating any token. The CLI will link you there directly when it triggers.

Example finding output:

[CRITICAL] 1 indicator matched: family=shai-hulud
  ↳ Read this before rotating any token: docs/SHAI-HULUD-FAILSAFE.md
[OK]       0 indicators matched: lockfiles, processes, github, mcp

Scanned 47 lockfiles · 234 processes · 12 MCP configs in 1.4s.
Coverage window: 2025-09-08 → present.

How it works

patient-zero fetches a single normalized IoC list (data/iocs.json) from GitHub once per hour, then runs five scanners in parallel against your machine, lockfiles, and GitHub account (opt-in). It does not phone home, does not collect telemetry, does not require a signup. The IoC list and the source feeds it aggregates from are public.

The IoC list is updated hourly by a GitHub Actions workflow that pulls from OSV.dev, GitHub Security Advisories, and a hand-curated data/manual-iocs.json. Source code: aggregator/.

CI usage

The composite action is the easiest way. It runs patient-zero, generates a SARIF report, and (combined with github/codeql-action/upload-sarif) populates the repo's Security tab inline with findings.

- uses: 0xSteph/patient-zero@v0.2
  id: patient-zero
  with:
    ecosystem: npm           # optional: restrict to one ecosystem
    fail-on: medium          # critical|high|medium|low|info

- uses: github/codeql-action/upload-sarif@v4
  if: always()
  with:
    sarif_file: patient-zero.sarif
    category: patient-zero

If you don't want the action and prefer to call the CLI directly:

- run: npx patient-zero@latest scan --no-github --json --sarif patient-zero.sarif > scan.json
- uses: github/codeql-action/upload-sarif@v4
  if: always()
  with:
    sarif_file: patient-zero.sarif

Both shapes produce SARIF v2.1.0 — GitHub's Security tab understands it natively.

Contributing a new IoC

We curate data/manual-iocs.json for attack indicators that only appear in blog posts and incident writeups. PR template:

  1. Read docs/IOC-SCHEMA.md for the field contract.
  2. Add your entries to data/manual-iocs.json.
  3. Open a PR with a one-line title: add IoCs for <attack-family> and a link to your source writeup.

A new attack family also needs an entry in attack_families and at minimum one external primary_external_source. We do not accept entries without an external source link.

Full guide →

Comparison

On-demand triage Install-time block CI / GH Action Process / local scan MCP-aware Open IoC DB Free, no signup
patient-zero ✓ (SARIF)
Aikido Safe Chain ✗ (closed)
Socket Free ✗ (closed) ✗ (signup)
osv-scanner
npq
Dependabot (GitHub native) ✓ (only on GitHub) ✓ (GitHub only)
Snyk Open Source partial ✗ (signup)
Cobenian/shai-hulud-detect partial ✓ (1 family)

The lockfile-malware row got crowded after Dependabot added native malware alerts in March 2026. patient-zero's bet for differentiation is on the columns most competitors leave empty: MCP / process / local persistence scanning, plus install-time blocking with an open IoC database.

We work alongside the continuous tools — not as a replacement. If you have Snyk in CI, keep it. patient-zero is what you reach for the moment a new supply-chain attack disclosure hits the news, and what you wire into npm install to catch the attack before postinstall runs.

Security disclosure

Found a vulnerability in patient-zero itself? See SECURITY.md.

Reporting a malicious package or compromised MCP server you found in the wild? Open a PR adding it to data/manual-iocs.json (see Contributing above), or email the maintainer link in SECURITY.md if disclosure needs to be coordinated.

License

MIT. See LICENSE.


Maintained by @0xSteph. Incident updates: @patientzerocli.

About

Supply-chain attack scanner for the agent era. Triage in 30s with `npx patient-zero`, block malicious installs before postinstall runs, or drop into CI as a GitHub Action. Covers npm + Python + MCP agent configs. Free, MIT, no signup, no telemetry.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors