adudley78/mcp-audit
GitHub: adudley78/mcp-audit
面向 MCP 服务器配置的开源安全扫描器,通过静态与实时分析检测工具投毒、凭据泄露、供应链欺诈及跨服务器攻击路径等风险。
Stars: 0 | Forks: 0
# mcp-audit
[](https://github.com/adudley78/mcp-audit/actions/workflows/ci.yml)
[](LICENSE)
[](https://github.com/sponsors/YOUR_HANDLE)
**面向 MCP 服务器配置的隐私优先安全扫描器。**
**免费且开源。** 采用 Apache 2.0 许可证,包含所有功能 —— 无需付费版本,无需
许可证密钥。如果该项目对您或您的团队有帮助,请考虑
[在 GitHub 上赞助开发](https://github.com/sponsors/YOUR_HANDLE)。
**隐私优先:** mcp-audit 不收集任何遥测数据。所有扫描均在本地运行。
完整政策请参见 [docs/telemetry.md](docs/telemetry.md)。
MCP (Model Context Protocol) 服务器赋予了 AI 代理访问您的工具、文件、API 和数据库的权限。配置错误或恶意服务器可以窃取凭据、污染工具行为并破坏您的开发环境 —— 而这一切在 UI 界面上毫无察觉。
`mcp-audit` 能够扫描您在所有主要 AI 编码客户端中的本地 MCP 配置,连接到正在运行的服务器以检查代理实际看到的内容,并标记出单个服务器的安全问题以及危险的跨服务器组合。
## 为什么漏洞管理对 MCP 安全至关重要
如今,MCP 安全发现都是孤立存在的。开发人员运行一次扫描器,查看终端输出,也许会修复一些问题。但是,在数百名开发人员中部署 AI 代理的企业需要与其他所有漏洞类别相同的工作流:将发现结果提取到集中式平台,与资产上下文相关联,跨扫描去重,分配所有权,跟踪修复情况并报告进度。
mcp-audit 的 `--format nucleus` 输出旨在与 Nucleus Security FlexConnect schema 对齐,将发现结果映射到标准提取字段(`asset_name`、`finding_number`、`finding_severity` 等) —— 这是同一个用于规范化 Qualys、Tenable、CrowdStrike 以及 200 多种其他安全工具数据的提取管道。(此集成尚未针对真实的 Nucleus 实例进行验证 —— 详见 `GAPS.md`。一旦验证通过,这意味着 MCP 服务器漏洞将与基础设施、云和应用程序漏洞一起出现在单个优先级视图中,并使用安全团队已在使用的相同自动化、SLA 跟踪和报告功能。)
Tenable WAS 已经添加了 MCP 服务器检测插件,可以扫描服务器端代码以查找 Web 漏洞 —— 但是目前没有独立的 MCP 配置扫描器能够填补开发人员侧配置分析(工具污染、凭据泄露、有害流程、供应链风险)与企业漏洞管理之间的空白。大多数工具只输出到终端或 JSON 就止步不前了。
## 功能特性
- **自动发现** 跨 8 种客户端(Claude Desktop, Cursor, VS Code, Windsurf, Claude Code 用户级, Claude Code 项目级, GitHub Copilot CLI, Augment Code)的 MCP 配置
- **工具投毒检测** —— 跨 5 个严重性层级的 11 种正则表达式模式
- **凭据泄露** —— 涵盖 AWS, GitHub, OpenAI, Anthropic, Stripe, Slack 和数据库 URL 的 9 种模式
- **传输安全** —— 未加密连接、提权执行、运行时包获取
- **供应链** —— 通过与 57 个已知合法 MCP 服务器的 Levenshtein 距离进行拼写欺诈检测
- **地毯式拉取检测** —— 跨扫描的工具描述的有状态 SHA-256 哈希比较
- **跨服务器有害流程** —— 能力标签和 7 种检测多服务器攻击路径的危险配对模式
- **攻击路径引擎** —— 使用贪婪命中集算法(移除以打破所有攻击路径的最小服务器集合)进行多跳路径检测
- **交互式攻击图仪表盘** —— `mcp-audit dashboard` 会在您的浏览器中打开一个 D3 力导向图,支持明/暗模式,点击高亮攻击路径以及命中集建议
- **实时服务器分析** —— 通过 MCP 协议连接到正在运行的服务器,以检查实际的工具定义
- **5 种输出格式** —— terminal (Rich), JSON, SARIF (GitHub Security tab), Nucleus FlexConnect, 自包含 HTML 仪表盘
- **持续监控** —— `mcp-audit watch` 实时监控配置文件并在任何更改时重新扫描
- **集群部署** —— 带有 `--asset-prefix` 的机器标记输出,用于企业级聚合
- **默认完全离线** —— 没有任何数据离开您的计算机
## 免费且开源
mcp-audit 在 [Apache License 2.0](LICENSE) 下发布,每位
用户都可以使用每一项功能。没有付费版本、许可证密钥
或受限命令 —— 完整的扫描器、规则编写、治理、SAST
集成、扩展扫描、仪表盘、集群合并以及 Nucleus
FlexConnect 输出全部集成在同一个二进制文件中。
## 安装
```
pip install mcp-audit-scanner
```
或者使用 [uv](https://docs.astral.sh/uv/):
```
uv add mcp-audit-scanner
```
对于实时服务器连接支持:
```
pip install 'mcp-audit-scanner[mcp]'
```
## 快速入门
```
mcp-audit scan # Scan all detected MCP configs
mcp-audit scan --connect # Also connect to running servers
mcp-audit scan --format sarif -o results.sarif # SARIF for GitHub Security
mcp-audit scan --format nucleus -o results.json # Nucleus FlexConnect output
mcp-audit dashboard # Open interactive attack graph dashboard
mcp-audit dashboard --path demo/configs # Dashboard against demo data
mcp-audit discover # List detected clients and servers
mcp-audit pin # Lock current state as trusted baseline
mcp-audit diff # Show changes since last pin
mcp-audit watch # Monitor configs and re-scan on changes
mcp-audit push-nucleus --url ... --project-id ... # Scan and push to a Nucleus project
mcp-audit merge --dir ./scans # Merge multi-machine JSON outputs
```
## 支持的客户端
| 客户端 | 配置位置 |
|--------|----------------|
| Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Cursor | `~/.cursor/mcp.json` |
| VS Code | `.vscode/mcp.json` (工作区) |
| Windsurf | `~/.codeium/windsurf/mcp_config.json` |
| Claude Code (用户级) | `~/.claude.json` |
| Claude Code (项目级) | `.mcp.json` (项目根目录) |
| GitHub Copilot CLI | `~/.copilot/mcp-config.json` |
| Augment Code | `~/.augment/settings.json` |
## 检测内容
| 分析器 | 发现 ID | 示例 |
|----------|-------------|---------|
| 工具投毒 | 11 种模式 (POISON-001 – POISON-050) | SSH 密钥窃取指令,XML 注入标记 (``),行为覆盖 ("ignore previous instructions"),零宽度 Unicode 隐形字符 |
| 凭据泄露 | CRED-001…009 | AWS 访问密钥,GitHub token,OpenAI/Anthropic API 密钥,Stripe 密钥,带有嵌入密码的数据库连接字符串 |
| 传输安全 | TRANSPORT-001…003 | 未加密的远程 SSE 连接,提权执行,通过无版本固定的 `npx`/`uvx` 获取运行时包 |
| 供应链 | SC-001…003 | 拼写欺诈的包名 (`@modelcontextprotocol/server-filesytem` 对比 `server-filesystem`),距离为 1 的替换会被标记为 CRITICAL |
| 地毯式拉取 | RUGPULL-001…003 | 自上次扫描以来工具描述发生更改 (HIGH),出现新服务器 (INFO),之前跟踪的服务器被移除 (INFO) |
| 有害流程 | TOXIC-001…007 | 文件读取服务器 + 网络服务器 (窃取路径),秘密访问服务器 + 网络服务器 (凭据窃取),Shell 执行服务器 + 网络服务器 (任意命令执行 + 窃取) |
## 实时服务器分析
默认情况下,`mcp-audit` 执行静态分析 —— 它读取配置文件并检查命令、参数、环境变量以及存储在其中的任何工具描述。
`--connect` 标志则更进一步:它使用 MCP 协议连接到每个服务器,完成初始化握手,并调用 `list_tools()`、`list_resources()` 和 `list_prompts()` 来检索服务器暴露给 AI 代理的实际定义。然后,这些实时定义将通过投毒分析器进行检测。
这一点非常重要,因为配置文件看起来可能完全干净,但它指向的服务器却可能在提供有毒的工具描述。静态分析无法捕捉到这一点。基于连接的分析可以做到。
```
mcp-audit scan --connect
```
需要可选的 MCP SDK 依赖:
```
pip install 'mcp-audit-scanner[mcp]'
```
连接是尽力而为的:在 10 秒内未响应的服务器会产生一个错误发现,而不是导致扫描崩溃。无论如何,所有的静态分析仍会运行。
## 跨服务器攻击路径
大多数 MCP 安全分析都集中在单个服务器上。这就遗漏了整整一类风险。
服务器 A 读取文件。服务器 B 发出 HTTP 请求。单独来看,两者都不是恶意的 —— 它们各自完全按照配置执行。然而结合起来,一次提示注入就可以指示代理使用 A 读取您的 SSH 密钥,并使用 B 将其 POST 到攻击者的端点。没有任何单个服务器看起来是危险的。
`mcp-audit` 通过为每个服务器标记能力标签(`FILE_READ`, `NETWORK_OUT`, `SHELL_EXEC`, `DATABASE`, `SECRETS` 等)并检查每个服务器对是否存在已知危险的组合,从而检测出 7 类这种有毒组合:
| ID | 组合 | 严重性 |
|----|-------------|----------|
| TOXIC-001 | 文件读取 + 出站网络 | HIGH |
| TOXIC-002 | 文件读取 + 电子邮件 | HIGH |
| TOXIC-003 | 密钥存储访问 + 出站网络 | CRITICAL |
| TOXIC-004 | 文件读取 + Shell 执行 | HIGH |
| TOXIC-005 | 数据库访问 + 出站网络 | HIGH |
| TOXIC-006 | Shell 执行 + 出站网络 | CRITICAL |
| TOXIC-007 | Git 仓库访问 + 出站网络 | MEDIUM |
† 提供危险配对两种能力的单一服务器也会被标记 —— 不需要第二个服务器。
## 攻击图仪表盘
```
mcp-audit dashboard # Scan your real MCP environment and open browser
mcp-audit dashboard --path demo/configs # Use the bundled demo data
mcp-audit dashboard --port 9090 # Custom port
mcp-audit dashboard --connect # Include live-connection findings
```
一个命令即可运行完整扫描,生成自包含的 HTML 报告,并在您的浏览器中将其打开。没有外部依赖项 —— D3 v7、所有扫描数据和字体均被内联嵌入。没有发出任何 CDN 请求。
仪表盘显示:
- **力导向攻击图** —— 您的 MCP 服务器围绕中心的 AI Agent 节点排列。服务器节点根据最大严重性进行颜色编码(绿色 = 干净,橙色 = 高危,红色 = 严重)。有害流程边缘将有危险能力组合的服务器对连接起来。
- **攻击路径侧边栏** —— 每个可利用的多跳路径都列为一张带有严重性徽章、跳链和描述的卡片。点击卡片可在图上以动画虚线高亮显示该路径。
- **命中集建议** —— 在侧边栏底部,显示了您可以移除以打破所有攻击路径的最小服务器集合。例如:仅移除 `fetch` 就能打破三个独立的攻击路径。
- **发现表格** —— 带有严重性过滤按钮和可排序列的完整发现列表。
- **明/暗模式切换** —— 顶部栏中的胶囊切换按钮。偏好设置通过 CSS 自定义属性立即应用;无需重新加载页面。
该仪表盘针对您真实的 MCP 环境运行 —— 无论 `mcp-audit scan` 在您的机器上发现了什么,都会显示在图表中。它不局限于演示数据。
## 地毯式拉取检测
MCP 服务器可以随时更新其工具定义。一个服务器可以在初次审查期间发布干净、可信的描述,并在开发人员授予访问权限后悄悄将其替换为恶意描述。
`mcp-audit pin` 记录每个受跟踪服务器配置的 SHA-256 哈希值,作为受信任的基线。随后的 `mcp-audit scan` 运行会与该基线进行比较,并将任何更改标记为 RUGPULL-001 (HIGH)。
```
mcp-audit pin # Record current state as trusted
mcp-audit diff # Show what has changed since last pin
```
地毯式拉取状态按配置集存储在 `~/.mcp-audit/state_.json` 中。所有其他持久状态(基线、注册表缓存、策略、规则、许可证)使用平台用户配置目录:macOS 上为 `~/Library/Application Support/mcp-audit/`,Linux 上为 `~/.config/mcp-audit/`,Windows 上为 `%APPDATA%\mcp-audit\`。
## CI/CD 使用
当检测到发现时,`mcp-audit` 以代码 `1` 退出;干净时以 `0` 退出;出错时以 `2` 退出。
```
# .github/workflows/mcp-security.yml
- name: Scan MCP configs
run: mcp-audit scan --severity-threshold HIGH
- name: Export SARIF for GitHub Security tab
run: mcp-audit scan --format sarif -o mcp-audit.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: mcp-audit.sarif
```
## 检测逻辑来源
所有检测模式均是基于已发布的安全研究自主实现的 —— 未从现有扫描器复制任何代码。来源包括 Invariant Labs 的工具投毒披露、CrowdStrike 的 MCP 窃取研究、CyberArk 的代理攻击演示、OWASP Agentic Top 10 和 MITRE ATLAS 代理特定技术。供应链模式遵循 npm 包命名约定;凭据模式遵循来自 AWS, GitHub, OpenAI, Anthropic, Stripe 等公开记录的密钥格式。
1,384 项测试验证了检测准确性,并防止出现回归问题。
有关研究来源、框架映射和新检测规则的贡献指南的完整列表,请参见 [PROVENANCE.md](PROVENANCE.md)。
## CLI 参考
每位用户都可以使用每个命令 —— 无版本限制,无需许可证| 命令 | 主要标志 | 描述 |
|---------|-----------|-------------|
| `mcp-audit scan` | `--connect`, `--format`, `--output`, `--severity-threshold`, `--asset-prefix`, `--baseline`, `--policy`, `--verify-hashes`, `--no-score`, `--registry`, `--offline-registry`, `--rules-dir`, `--sast`, `--include-extensions` | 运行所有分析器并报告发现 |
| `mcp-audit dashboard` | `--path`, `--port`, `--connect`, `--no-open` | 生成并打开交互式攻击图仪表盘 |
| `mcp-audit watch` | `--path`, `--format`, `--severity-threshold`, `--connect` | 监控配置文件并在任何更改时重新扫描 |
| `mcp-audit discover` | — | 列出所有检测到的 MCP 客户端及其配置的服务器 |
| `mcp-audit pin` | — | 将当前服务器状态记录为受信任的基线 |
| `mcp-audit diff` | — | 显示自上次 `pin` 以来的配置更改 |
| `mcp-audit verify` | `` | 验证服务器哈希:传递包名 (`@scope/pkg`)、配置文件路径或 `--all` |
| `mcp-audit activate` | `` | 遗留功能 —— 验证以前颁发的许可证密钥(保留以实现兼容性) |
| `mcp-audit license` | — | 遗留功能 —— 显示以前激活的密钥的详细信息 |
| `mcp-audit version` | — | 打印版本字符串 |
| `mcp-audit update-registry` | — | 从上游获取最新的已知服务器注册表 |
| `mcp-audit sast` | `` | 在服务器源代码上运行 MCP 感知的 Semgrep SAST 规则 |
| `mcp-audit push-nucleus` | `--url`, `--project-id`, `--api-key`, `--asset-prefix` | 运行扫描并通过 FlexConnect 将结果推送到 Nucleus Security 项目 |
| `mcp-audit merge` | `--dir`, `--format`, `--asset-prefix` | 将来自多台机器的 JSON 扫描输出合并到集群报告中 |
| `mcp-audit baseline save [NAME]` | `--path` | 捕获基线快照;NAME 是可选的(如果省略则自动生成) |
| `mcp-audit baseline list` | — | 列出所有已保存的基线 |
| `mcp-audit baseline compare [NAME]` | `--path` | 将当前配置与已保存的基线进行比较(默认为最新) |
| `mcp-audit baseline delete NAME` | `--yes` | 删除已保存的基线 |
| `mcp-audit baseline export NAME` | `--output-file` | 将基线作为原始 JSON 写入标准输出或文件 |
| `mcp-audit rule validate` | `` | 在不运行扫描的情况下验证规则文件 |
| `mcp-audit rule test` | ` ` | 针对特定 MCP 配置文件测试规则文件 |
| `mcp-audit rule list` | — | 列出所有当前加载的规则(捆绑 + 用户本地) |
| `mcp-audit policy validate` | `` | 验证治理策略 YAML 文件 |
| `mcp-audit policy init` | — | 脚手架生成新的治理策略文件 |
| `mcp-audit policy check` | `--policy`, `--result` | 根据策略文件检查扫描结果 |
| `mcp-audit extensions discover` | — | 清点已安装的 VS Code/Cursor IDE 扩展 |
| `mcp-audit extensions scan` | — | 分析已安装的 IDE 扩展以发现安全风险 |
**`mcp-audit scan` 标志**
| 标志 | 默认值 | 描述 |
|------|---------|-------------|
| `--format` | `terminal` | 输出格式:`terminal`, `json`, `sarif`, `nucleus` |
| `--output / --output-file / -o` | stdout | `json`/`sarif`/`nucleus` 输出的文件路径;父目录会自动创建 |
| `--connect` | off | 通过 MCP 协议连接到正在运行的服务器 |
| `--severity-threshold` | `INFO` | 过滤发现并设置退出代码;如果存在任何等于或高于此级别的发现,则以 1 退出 |
| `--path` | 自动检测 | 搜索 MCP 配置的目录 |
| `--asset-prefix` | 主机名 | 覆盖 Nucleus/SARIF 输出中的机器标识符 |
| `--no-score` | off | 抑制终端输出中的评分/等级面板 |
| `--registry` | 捆绑 | 自定义注册表文件路径(覆盖用户缓存和捆绑的注册表) |
| `--baseline` | 无 | 将扫描结果与指定名称的基线进行比较(`latest` 选择最近的) |
| `--rules-dir` | 无 | 从此目录加载额外的检测规则(捆绑的社区规则仍会应用) |
| `--offline-registry` | off | 仅使用捆绑的注册表,跳过用户缓存 |
| `--policy` | 自动发现 | 治理策略文件的路径;省略时会在 cwd/仓库根目录自动发现 `.mcp-audit-policy.yml` |
| `--verify-hashes` | off | 下载并根据注册表验证包哈希(需要网络) |
| `--sast` | 无 | 要使用 Semgrep SAST 规则扫描的 MCP 服务器源代码路径 |
| `--include-extensions` | off | 同时扫描已安装的 IDE 扩展以查找安全问题 |
**`mcp-audit dashboard` 标志**
| 标志 | 默认值 | 描述 |
|------|---------|-------------|
| `--path` | 自动检测 | 搜索 MCP 配置的目录 |
| `--port` | `8088` | 本地仪表盘服务器的 HTTP 端口 |
| `--connect` | off | 在仪表盘中包含实时连接的发现 |
| `--no-open` | off | 生成报告而不打开浏览器标签页 |
## GitHub Action
[](https://github.com/adudley78/mcp-audit/actions/workflows/mcp-audit-example.yml)
`mcp-audit` 作为 [composite GitHub Action](action.yml) 发布,您只需添加一个工作流即可将其放入任何代码库。它会安装 `mcp-audit`,对您的 MCP 配置运行完整扫描,将发现作为 SARIF 上传到 GitHub Security 标签页,并将发现摘要写入作业摘要页面。仅当存在等于或高于您选择的严重性阈值的发现时,构建才会失败 —— 这使得增量采用变得容易(从 `severity-threshold: high` 开始,清除现有问题后再收紧到 `medium`)。
### 最小设置
将此工作流添加到您代码库的 `.github/workflows/mcp-audit.yml` 中:
```
name: MCP Security Scan
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
mcp-audit:
runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Run mcp-audit
uses: adudley78/mcp-audit@main
with:
severity-threshold: high
upload-sarif: 'true'
```
对于公共仓库,SARIF 上传必须拥有 `permissions: security-events: write` 权限块。没有它,上传步骤将静默失败。
### Action 输入
| 输入 | 默认值 | 描述 |
|-------|---------|-------------|
| `severity-threshold` | `high` | 如果存在等于或高于此级别的发现,则导致构建失败 (`critical`, `high`, `medium`, `low`, `info`) |
| `format` | `sarif` | 输出格式 (`sarif`, `json`, `terminal`) |
| `config-paths` | _(自动发现)_ | 要扫描的单个 MCP 配置文件路径 |
| `baseline` | _(无)_ | 用于偏差检测的基线名称 |
| `upload-sarif` | `true` | 将 SARIF 结果上传到 GitHub Security 标签页 |
### Action 输出
| 输出 | 描述 |
|--------|-------------|
| `finding-count` | 发现总数 |
| `grade` | 字母等级 (A–F) |
| `sarif-path` | 生成的 SARIF 文件的路径 |
### 更多示例
有关以下内容,请参见 [`examples/github-actions/`](examples/github-actions/):
- [`basic.yml`](examples/github-actions/basic.yml) —— 仅可视化,永远不会导致构建失败
- [`strict.yml`](examples/github-actions/strict.yml) —— 任何 MEDIUM 或更高级别的发现都会导致失败
- [`with-baseline.yml`](examples/github-actions/with-baseline.yml) —— 针对提交的基线进行偏差检测
完整参考、故障排除和基线设置说明:[`docs/github-action.md`](docs/github-action.md)。
## Pre-Commit Hook
`mcp-audit` 作为 [pre-commit](https://pre-commit.com) hook 发布,可在 MCP 错误配置进入代码库之前将其拦截。该 hook 仅在暂存了 JSON 文件时触发 —— 不会对纯 Python 或纯 markdown 的提交产生误触发 —— 并且当存在等于或高于您选择的严重性阈值的发现时,它会以退出码 1 阻止提交。
### 最小设置
将此内容添加到您的 `.pre-commit-config.yaml` 中(将 `rev` 替换为[最新发布标签](https://github.com/adudley78/mcp-audit/releases)):
```
repos:
- repo: https://github.com/adudley78/mcp-audit
rev: v0.1.0 # Replace with the latest release tag
hooks:
- id: mcp-audit
```
然后安装 hooks:
```
pip install pre-commit
pre-commit install
```
该 hook 默认使用 `--severity-threshold high`。要降低标准至 MEDIUM,请覆盖 `args`:
```
hooks:
- id: mcp-audit
args: [scan, --severity-threshold, medium]
```
**注意:** `pass_filenames: false` 是有意设置的。pre-commit 否则会将单个暂存的 JSON 文件名传递给命令,但 `mcp-audit scan` 需要通过其自身的客户端感知逻辑发现的完整配置文件。该 hook 每次触发时都会重新扫描所有的 MCP 配置(而不仅仅是暂存的那些)。
有关可直接复制的配置模式,请参见 [`examples/pre-commit/`](examples/pre-commit/);有关完整参考,请参见 [`docs/pre-commit.md`](docs/pre-commit.md)。
## 开发
```
git clone https://github.com/adudley78/mcp-audit.git
cd mcp-audit
uv sync --all-extras
uv run pytest # Run all 1,384 tests
uv run ruff check src/ tests/ # Lint
uv run bandit -r src/ # Security audit of the scanner itself
```
## 已知局限性
此工具处于早期开发阶段。有关已知的检测漏洞、未测试领域和计划改进,请参见 [GAPS.md](GAPS.md)。
## 许可证
Apache License 2.0 —— 详见 [LICENSE](LICENSE)。
标签:AI Agent安全, AI安全, AMSI绕过, Chat Copilot, CISA项目, DevSecOps, GPT, MCP, Model Context Protocol, Nucleus Security, SARIF, 上游代理, 人工智能, 供应链风险, 凭证暴露, 合规, 威胁检测, 安全扫描, 开发安全, 提示注入, 文档安全, 时序注入, 本地扫描, 漏洞管理, 用户模式Hook绕过, 网络安全, 逆向工具, 隐私保护, 集群管理