0xSteph/patient-zero
GitHub: 0xSteph/patient-zero
面向 AI Agent 时代的供应链攻击扫描器,覆盖 npm、Python 及 MCP 配置,支持按需扫描、安装时拦截和 CI 集成三种模式。
Stars: 10 | Forks: 4
# patient-zero
扫描 Node、Python 和 AI-agent 配置,查找自 2025 年 9 月至今 npm 和 PyPI 供应链攻击的入侵指标(IoC)。30 秒内完成分类,在 postinstall 运行前拦截恶意安装,或者将其接入你的 CI —— 同一个 IoC 数据库,三种模式,一条命令。
[](https://www.npmjs.com/package/patient-zero)
[](https://www.npmjs.com/package/patient-zero)
[](https://github.com/0xSteph/patient-zero/actions)
[](LICENSE)
[](package.json)
[](#how-it-works)
[](#how-it-works)
[](#how-it-works)
```
$ 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
```
## 三种使用方式
### 1. 按需分类 —— 当新闻爆出时
```
npx patient-zero@latest
```
无需全局安装,无需注册,无需配置。针对当前目录运行。当 chalk / axios / 最新的 Shai-Hulud 变种上了 Hacker News,而你急需快速确认你的机器是否受影响时,请使用此方式。
### 2. 安装时拦截 —— 在恶意软件运行*之前*将其捕获
```
npx patient-zero@latest install
```
在沙盒临时目录中解析拟议的安装树,将每个传递依赖与 IoC 数据库进行交叉比对,并在匹配到任何指标时拒绝继续执行。**postinstall 脚本永远不会执行。** 这是 agent 时代最具价值的单一功能 —— 你的 AI agent 代表你安装东西;你不可能看到每一次安装;而它会将其捕获。
### 3. 持续 CI —— 覆盖每一次提交和每一个 PR
```
- uses: 0xSteph/patient-zero@v0.2
with:
fail-on: medium
```
无缝接入任何 GitHub Actions 工作流。生成 SARIF 报告,并自动填充到 GitHub 的 Security 标签页中。无需 token,无需 Snyk 式的注册,没有按席位收费的定价。
或者作为 pre-commit hook:
```
npx patient-zero install-hook
```
自动检测 husky / lefthook / pre-commit / 原生 git hooks,并将 patient-zero 接入到正确的位置。操作具备幂等性且可移除。
## 扫描范围
- **AI-agent MCP 配置** —— Claude Desktop, Claude Code, Cursor, Cline。检测已知的恶意服务器、`@modelcontextprotocol/*` 的域名抢注、非 HTTPS URL,以及 env 块中的敏感凭证。[没有其他工具覆盖这一领域。](docs/MCP-IOC-GUIDE.md)
- **正在运行的进程** —— 匹配已知的恶意 daemon(例如 Shai-Hulud 的 `gh-token-monitor`)。
- **本地持久化** —— `~/Library/LaunchAgents/` (macOS), `~/.config/systemd/user/` (Linux), `~/.npmrc`, `~/.pypirc`。
- **npm + Python lockfile** —— `package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, `requirements.txt`, `poetry.lock`。支持语义化版本号匹配。
- **你的 GitHub 账户**(可选) —— 使用 `gh` CLI 或你提供的 PAT。查找由被盗凭证创建的、符合已知攻击模式的仓库。
[查看完整的 IoC 列表 →](data/iocs.json) · [Schema →](docs/IOC-SCHEMA.md) · [MCP IoC 指南 →](docs/MCP-IOC-GUIDE.md)
## 本项目“不是”什么
- 不是 EDR 或运行时沙盒。
- 不是 Snyk 或 Socket 等持续监控工具的替代品 —— 而是与它们协同工作。
- 不是漏洞扫描器(我们扫描已知的恶意指标,而不是 CVE)。
我们明确的主张:大部分核心价值在于覆盖 GitHub *之外*的盲区(MCP 配置、进程、本地持久化)以及安装时的拦截。截至 2026 年 3 月,GitHub 的 Dependabot 已经在原生的 lockfile 恶意软件检测中覆盖了部分领域;我们则专注于它尚未覆盖的部分。
## 已覆盖的攻击
从 [`data/iocs.json`](data/iocs.json) 自动生成。要添加新的攻击家族,请参阅 [CONTRIBUTING.md](docs/CONTRIBUTING.md)。
| 攻击家族 | 首次发现 | 生态系统 | IoC 类别 | 来源 |
|---|---|---|---|---|
| Shai-Hulud | 2025-09-15 | npm | package + file + process + github | [StepSecurity](https://www.stepsecurity.io/blog/) |
| chalk 维护者钓鱼 | 2025-09-08 | npm | package | [Snyk Advisory](https://security.snyk.io/) |
| SANDWORM_MODE | 2025-11-01 | npm | package + network | [Socket](https://socket.dev/blog) |
| Shai-Hulud 2.0 | 2025-12-09 | npm | package + file + process + github | [Microsoft](https://www.microsoft.com/en-us/security/blog/2025/12/09/shai-hulud-2-0-guidance-for-detecting-investigating-and-defending-against-the-supply-chain-attack/) |
| axios postinstall | 2026-03-12 | npm | package + network | [GHSA](https://github.com/advisories) |
| Mini Shai-Hulud (TanStack) | 2026-05-01 | npm | package | [StepSecurity](https://www.stepsecurity.io/blog/mini-shai-hulud-is-back-a-self-spreading-supply-chain-attack-hits-the-npm-ecosystem) |
追踪 **6 个已命名的攻击活动 + 1 个启发式家族(MCP 供应链模式) · 6 项指标 · 覆盖窗口 2025-09-08 至今。** (由[聚合工作流](.github/workflows/aggregator.yml)每小时自动更新;本行的数字是 v0.2.0 的静态快照。)
## 退出代码
供 CI 使用。在所有三种模式下契约相同。
```
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.
```
## 如果 patient-zero 标记了某些内容
不要惊慌,先不要吊销 token。请先阅读 [`docs/RESPONSE.md`](docs/RESPONSE.md) —— 其中包含针对各个攻击家族的分类处理步骤。
**关于 Shai-Hulud 家族发现的严重警告:** `gh-token-monitor` daemon 具有破坏性的故障保护机制。如果 patient-zero 显示了 Shai-Hulud 的发现,请在**轮换任何 token 之前**阅读 [`docs/SHAI-HULUD-FAILSAFE.md`](docs/SHAI-HULUD-FAILSAFE.md)。当它被触发时,CLI 会直接为你提供该文档的链接。
示例发现输出:
```
[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.
```
## 工作原理
patient-zero 每小时从 GitHub 获取一次标准化的 IoC 列表([`data/iocs.json`](data/iocs.json)),然后针对你的机器、lockfile 和 GitHub 账户(可选)并行运行五个扫描器。它不会进行外部网络通信,不收集遥测数据,也不需要注册。IoC 列表及其聚合的源数据源都是公开的。
IoC 列表由 [GitHub Actions 工作流](.github/workflows/aggregator.yml)每小时更新一次,数据拉取自 OSV.dev、GitHub Security Advisories 以及人工维护的 [`data/manual-iocs.json`](data/manual-iocs.json)。源代码:[`aggregator/`](aggregator/)。
## CI 用法
使用 composite action 是最简单的方式。它会运行 patient-zero,生成 SARIF 报告,并(结合 `github/codeql-action/upload-sarif`)自动将发现结果以内联方式填充到仓库的 Security 标签页中。
```
- 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
```
如果你不想使用该 action,而是倾向于直接调用 CLI:
```
- 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
```
两种形式都会生成 SARIF v2.1.0 —— GitHub 的 Security 标签页原生支持该格式。
## 贡献新的 IoC
我们整理 `data/manual-iocs.json`,用于记录那些仅出现在博客文章和事件报告中的攻击指标。PR 模板如下:
1. 阅读 [`docs/IOC-SCHEMA.md`](docs/IOC-SCHEMA.md) 了解字段契约。
2. 将你的条目添加到 `data/manual-iocs.json`。
3. 提交一个标题为 `add IoCs for ` 的 PR,并附上你的源报告链接。
一个全新的攻击家族还需要在 `attack_families` 中添加条目,并至少提供一个外部的 `primary_external_source`。我们不接受没有外部源链接的条目。
[完整指南 →](docs/CONTRIBUTING.md)
## 横向对比
| | 按需分类 | 安装时拦截 | CI / GH Action | 进程 / 本地扫描 | 支持 MCP | 开放 IoC 数据库 | 免费且无需注册 |
|---|---|---|---|---|---|---|---|
| **patient-zero** | ✓ | ✓ | ✓ (SARIF) | ✓ | ✓ | ✓ | ✓ |
| [Aikido Safe Chain](https://github.com/AikidoSec/safe-chain) | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ (闭源) | ✓ |
| [Socket](https://socket.dev/) 免费版 | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ (闭源) | ✗ (需注册) |
| [osv-scanner](https://github.com/google/osv-scanner) | ✓ | ✗ | ✓ | ✗ | ✗ | ✓ | ✓ |
| [npq](https://github.com/lirantal/npq) | ✗ | ✓ | ✗ | ✗ | ✗ | ✓ | ✓ |
| Dependabot (GitHub 原生) | ✗ | ✗ | ✓ (仅限 GitHub) | ✗ | ✗ | ✓ | ✓ (仅限 GitHub) |
| Snyk Open Source | 部分 | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ (需注册) |
| [Cobenian/shai-hulud-detect](https://github.com/Cobenian/shai-hulud-detect) | ✓ | ✗ | ✗ | 部分 | ✗ | ✓ (1 个家族) | ✓ |
自从 Dependabot 在 2026 年 3 月添加了原生的恶意软件警报后,lockfile 恶意软件这一领域的竞争变得愈发激烈。patient-zero 的差异化优势押注在大多数竞争对手留空的列上:**MCP / 进程 / 本地持久化扫描,以及结合开放 IoC 数据库的安装时拦截**。
我们与持续监控工具并行工作 —— 并非为了替代它们。如果你在 CI 中使用了 Snyk,请继续保留。patient-zero 是当新的供应链攻击披露上了新闻时,你第一时间会伸手去用的工具;也是你会接入到 `npm install` 中,以便在 postinstall 运行前捕获攻击的工具。
## 安全披露
发现了 patient-zero 本身的漏洞?请参阅 [`SECURITY.md`](SECURITY.md)。
想要报告在野外发现的恶意 package 或被入侵的 MCP 服务器?请提交一个将其添加到 `data/manual-iocs.json` 的 PR(参见上文的贡献指南),或者如果披露需要协调处理,请发送邮件至 `SECURITY.md` 中提供的维护者链接。
## 许可证
MIT。详见 [`LICENSE`](LICENSE)。
由 [@0xSteph](https://github.com/0xSteph) 维护。事件更新:[@patientzerocli](https://twitter.com/patientzerocli)。
或者观看 12 秒的动画演示
标签:GNU通用公共许可证, MITM代理, Node.js, Python, 安全扫描, 文档安全, 无后门, 时序注入, 暗色界面, 自定义脚本, 逆向工具, 配置审计