caglarbozkurt/mcp-heimdall
GitHub: caglarbozkurt/mcp-heimdall
Heimdall 是一款 MCP 服务器安全扫描器,在开发者将第三方或本地 MCP 服务器接入 AI Agent 之前,对其潜在的 prompt 注入、凭证泄露、RCE 及供应链风险进行静态与行为分析。
Stars: 0 | Forks: 0

# Heimdall
**你 Agent 门户的守卫者。**
一款针对 **Model Context Protocol (MCP) 服务器** 的安全扫描器 —— 在你的 Agent 信任它之前,对单个服务器,
或整个 Agent 配置进行审查。
[](https://www.npmjs.com/package/mcp-heimdall-scan)
[](https://github.com/caglarbozkurt/mcp-heimdall/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/mcp-heimdall-scan)
[](LICENSE)
[](package.json)
[](https://caglarbozkurt.github.io/mcp-heimdall)
MCP 服务器是未经审查的代码,具有自然语言攻击面:它们的工具描述会直接发送给你的模型,并且服务器会以你机器的访问权限运行。
Heimdall 评估的是 **服务器实际能做什么** —— 而不是它声称能做什么 —— 并提供确切的证据。
## 快速开始
```
npx mcp-heimdall-scan firecrawl-mcp # scan a published server
npx mcp-heimdall-scan ./claude_desktop_config.json # audit your whole agent config
npx mcp-heimdall-scan firecrawl-mcp --online # + check its deps for known CVEs (OSV.dev)
npx mcp-heimdall-scan ./my-server --policy strict # gate it in CI
```
无需安装,在本地运行,不会有任何数据离开你的机器。
**或者在浏览器中试用:** [caglarbozkurt.github.io/mcp-heimdall](https://caglarbozkurt.github.io/mcp-heimdall)
—— 完整的扫描器 **100% 在客户端运行**(npm 包通过 jsDelivr 获取;或者粘贴一个
`tools.json` / MCP 配置)。无后端,不上传任何内容。本地路径和 `--handshake` 需要 CLI。
## 检查内容
| 检查项 | 识别内容 |
|---|---|
| 🧬 **注入** | 跨工具、资源和 prompt 的工具投毒 —— 覆盖、隐藏、不可见字符、伪造的 `
` 标签 |
| 🔓 **能力** | 文件系统、网络、shell、`eval` 以及特定的凭证访问(SSH / AWS / keychain / `.env`) |
| 🎯 **已验证的泄露路径** | *证明* `secret -> 网络` 或 `fetch -> eval` 的数据流,精确到 `文件:行号 -> 文件:行号` |
| 📦 **来源与依赖** | 安装时脚本、缺失的 repo/license、从依赖项继承的能力 |
| 🛡️ **已知 CVE** *(选填)* | 将声明的依赖项与 OSV.dev 咨询数据库进行核对 —— 真实的 CVE ID,按严重性排名 (`--online`) |
| 🕸️ **组合风险** | 审计整个配置:跨服务器的数据泄露链和工具名称冲突 |
| 🔁 **漂移** | 对暴露面进行指纹识别 —— 静默更改的工具描述(rug-pull 抽地毯式骗局)将直接判定为严重失败 |
每项发现都会提供 `文件:行号` 或 `工具:名称` 作为依据。**能力 ≠ 风险:** 原始能力仅作为
信息展示,绝不会导致扫描失败 —— 只有严格的 **拦截门** 和真正的 **异常** 才会导致失败。
## 独特之处
- **统揽全局。** 它会对*整个集合*中你配置的服务器进行推理分析 ——
识别出单个服务器无法显现的跨服务器数据泄露路径。大多数扫描器一次只能看到一个。
- **验证路径。** 污点/数据流分析将“读取文件且具备网络能力 = 失败”转化为
具体、有明确位置的流程 —— 因此它不会对配置读取加上无关的 API 调用产生误报。
- **由你掌控的拦截门。** 检测器输出事实;由你定义的 **策略** 将其转化为
通过 / 警告 / 失败。拒绝特定能力、要求提供来源、添加已审查的豁免、对 CI 进行拦截。
## 使用方法
```
heimdall [options]
```
| 目标 | 示例 |
|---|---|
| 本地目录 | `heimdall ./servers/my-mcp` |
| npm 包 | `heimdall some-mcp-package` |
| PyPI 包 | `heimdall pypi:some-mcp-server` |
| git 仓库 | `heimdall https://github.com/user/repo` |
| tools/list 转储 | `heimdall tools.json` |
| MCP 客户端配置 | `heimdall ./claude_desktop_config.json` |
选项
```
--tools supplement analysis with a tools/list (or {tools,resources,prompts}) dump
--policy "default", "strict", or a JSON policy file
--baseline diff against a prior --json report (drift / rug-pull detection)
--handshake RUN the server(s) for the live tool list (untrusted code — VM/container only)
--online check declared deps against OSV.dev for known CVEs (sends dep names, not source)
--json machine-readable report
--sarif SARIF 2.1.0 (GitHub code-scanning / CI)
--no-fail always exit 0
Exit codes: 0 pass/warn · 1 fail · 2 error
```
## 策略
检测器输出事实;由 **策略** 决定最终结论。你可以使用默认策略、选择
`strict`,或者编写你自己的采购/安全标准:
示例策略 (policy.example.json)
```
{
"name": "acme-procurement",
"denyCapabilities": ["exec", "dynamic-eval", "secret-access"],
"require": ["has_repository", "has_license"],
"failOnSeverity": "high",
"warnOnSeverity": "low",
"allow": [{ "id": "capability/scope-mismatch", "reason": "reviewed", "expires": "2026-12-31" }]
}
```
豁免项包含原因和可选的过期时间 —— 过期的豁免将失效并重新触发警告。
## 库
```
import { scan } from "mcp-heimdall-scan";
const report = await scan("some-mcp-server", { policy: "strict" });
if (report.verdict === "fail") throw new Error(report.reasons.join("; "));
```
同时也作为 **Claude Code skill** (`skill/`) 提供 —— 可在安装前,于对话中直接审查服务器。
## 验证(行为交叉核对)
静态分析说明服务器*能*做什么。`heimdall validate` 会将其与它*实际*做的事进行核对 —— 它会预加载一个能力记录器来运行服务器(hook
`fs` / `net` / `http(s)` / `child_process` / `vm` / `fetch` / `process.env`),驱动每个工具,
并将观察到的运行时行为与静态标记进行比对:
```
heimdall validate ./my-server # one server: confirmed / missed / not-exercised
heimdall validate --list servers.txt # batch: a recall number over observed behavior
```
- **confirmed(已确认)** —— 已标记 *且* 被观察到(静态分析结论成立)。
- **not exercised(未触发)** —— 已标记但未被基础参数触发(这是一个*下限*,**并**不能证明标记是错误的)。
- **missed(遗漏)** —— 被观察到但**未**被标记 → 需要审查的静态分析盲区(或者是库带来的偶然副作用)。
因此,它对于查找假 **阴性**(静态分析遗漏)是可靠的;它并不能推翻已有的标记。
每个服务器都在一个临时的 `HOME` 和工作目录中运行,不继承任何凭证,但它仍会
**运行服务器并调用其工具**(可能产生网络/exec 副作用) —— 请使用一次性的 VM/container。
**对 200 个真实包的行为验证运行** ([`benchmarks/validate-run.md`](benchmarks/validate-run.md)):
55 个成功启动,34 个执行了可观察到的能力。在服务器*在运行时实际执行的*能力中,
静态扫描标记了 **80.9%** (55/68) —— 这一比例较首次运行后的 75.8% 有所提升(首次运行的遗漏成为了修复清单,我们扩展了基于依赖的网络检测,
这使网络检测遗漏减少了近一半)。剩下的遗漏是 **结构性问题**:即
在*依赖项内部或子进程中*执行的能力,静态分析根本无法察觉 —— 这也正是 `validate`
作为兜底方案存在的意义。客观的召回率,公开透明的报告,每次运行都在不断改进。
## 大规模测试
针对 npm registry 中的 **2,500 个真实 MCP 包** 运行 (`benchmarks/`):**约 5 分钟内扫描了 1,726 个**,
**0.7% 被标记** —— 在杂乱的真实代码上表现稳健。另外,在小型标注语料库上实现了 **100%
精确率 / 召回率** (`npm run eval`),其中包括 Damn Vulnerable
MCP 项目。完整日志:[`benchmarks/field-run.md`](benchmarks/field-run.md)。
该扫描结果对你 Agent 所信任的生态系统意味着:
| 在 1,726 个真实的 MCP 服务器中…… | 占比 |
|---|---|
| 能 **运行 shell 命令** | 45% |
| 发起 **网络调用** | 67% |
| 能在运行时 **`eval` 代码** | 9% |
| 能 **同时执行和网络调用** | 34% |
| 接触 **凭证文件** | 5% |
被标记的 0.7% 主要是因为安装时的代码执行和 prompt 注入 —— 包括
真实服务器中**在工具描述里嵌入了隐藏的零宽字符**,这种隐形工具投毒是关键词扫描器无法察觉的。
## 安全性与局限性
Heimdall 是一种 **启发式预检,并非绝对的保证** —— PASS 不代表绝对安全。
能力、来源和 CVE 分析覆盖 **JS/TS 和 Python**;注入检测则是语言无关的。已验证的
污点/数据流分析 **仅限 JS/TS** —— 对于 Python 则降级为
能力共存检测(一种保守的拦截机制,而非已验证的数据流)。
默认情况下,所有操作均在离线状态下运行;`--online` 是唯一的网络调用(它将依赖
名称和版本发送至 OSV.dev,绝不发送你的源代码),并且 CVE 匹配是基于声明的
范围,而不是 lockfile。`--handshake` **会运行不受信任的代码**,且并不是一个真正的 sandbox。有关
完整的威胁模型以及如何报告漏洞,请参阅 [`SECURITY.md`](SECURITY.md)。
## 贡献
新的检测规则是价值最高的贡献 —— 参见
[`CONTRIBUTING.md`](CONTRIBUTING.md)。参与即表示你同意
[行为准则](CODE_OF_CONDUCT.md)。
## License
[MIT](LICENSE) · 由 [Çağlar Bozkurt](https://github.com/caglarbozkurt) 构建标签:DLL 劫持, MCP安全, MITM代理, 云安全监控, 大语言模型, 安全扫描, 数据可视化, 时序注入, 暗色界面, 自动化攻击, 静态分析