CobaltoSec/corvus
GitHub: CobaltoSec/corvus
Corvus 是一款针对 MCP 服务器的安全测试框架,通过静态分析与动态探测覆盖 OWASP MCP Top 10 漏洞,帮助开发者在接入 LLM 工具链前发现并修复安全风险。
Stars: 1 | Forks: 0
# Corvus
[](https://pypi.org/project/cobaltosec-corvus/)
[](https://github.com/CobaltoSec/corvus/actions)
[](https://pypi.org/project/cobaltosec-corvus/)
MCP server 安全测试框架。针对 MCP server 进行 [OWASP MCP Top 10](https://owasp.org/www-project-top-10-for-large-language-model-applications/) 测试 —— 包含静态分析和实时动态探测。
```
Corvus v1.3.1 MCP Security Scanner
Target : python my_mcp_server.py
Transport : stdio
Modules : tool-poisoning, scope-audit, shadow-tool, supply-chain, osv-supply-chain,
github-advisory, npm-behavior, supply-chain-python, auth-audit, log-audit,
schema-audit, resource-uri, tool-chaining, cmd-injection, token-exposure,
ssrf, endpoint-probe, param-smuggling, schema-bypass, proto-fuzz, batch-dos,
output-encoding, response-flood, response-injection, rug-pull, init-audit,
oauth-bypass, sampling-probe, elicitation-probe, completion-probe,
logging-probe, prompts-injection, cursor-probe, cancellation-probe
Enumerating surface...
Tools : 12
Resources : 3
Prompts : 2
Server : my-server 1.0.0
[MCP03] Tool Poisoning (static)
[HIGH] Potential prompt injection in description of 'execute_code'
[MCP05] Command Injection (dynamic)
[HIGH] Command injection confirmed in tool 'run_shell', param 'command'
[MEDIUM] Path traversal accepted in tool 'read_file', param 'path'
...
─── Summary ──────────────────────────────────────────────────────────────────
CRITICAL 0 HIGH 2 MEDIUM 1 LOW 3 INFO 4
Risk Score: 56 / 100 (HIGH)
Session : corvus-sessions/20260608-143022/
```
## 安装
```
pip install cobaltosec-corvus
```
或从源码安装:
```
git clone https://github.com/CobaltoSec/corvus
cd corvus
pip install -e ".[dev]"
```
## 快速开始
```
# 立即尝试 — 使用单个命令扫描真实的 MCP server(需要 Node.js):
pip install cobaltosec-corvus
corvus scan "npx -y @modelcontextprotocol/server-filesystem /tmp"
```
```
# 扫描 stdio MCP server
corvus scan --transport stdio --cmd "python my_server.py"
# 扫描 HTTP MCP server
corvus scan --transport http --url http://localhost:8080
# 带有 authentication header
corvus scan --transport http --url http://localhost:8080 --header "Authorization: Bearer token"
# 仅静态分析(无 live tool calls)
corvus scan --transport stdio --cmd "python my_server.py" --module static
# 特定 module
corvus scan --transport stdio --cmd "python my_server.py" --module cmd-injection
# SARIF 输出(用于 CI/CD 集成)
corvus scan --transport stdio --cmd "python my_server.py" --sarif
# 在发现的问题超过阈值时使 CI 失败
corvus scan --transport stdio --cmd "python my_server.py" --fail-on high
# 从文件加载 config
corvus scan --config corvus.toml
# 过滤低置信度的发现(0-100)
corvus scan --transport stdio --cmd "python my_server.py" --min-confidence 70
# 捕获原始 JSON-RPC 交换
corvus scan --transport stdio --cmd "python my_server.py" --log-requests
# Rate-limit 探测(请求之间的毫秒数)
corvus scan --transport stdio --cmd "python my_server.py" --delay 500
# 将环境变量传递给 server 进程
corvus scan --transport stdio --cmd "python my_server.py" --env API_KEY=secret --env DEBUG=1
# 在结束时打印 Risk Score
corvus scan --transport stdio --cmd "python my_server.py" --score
# 列出可用的 modules
corvus list-modules
```
## 批量扫描
在一次调用中扫描多个 MCP server:
```
# targets.yaml
targets:
- name: filesystem
transport: stdio
cmd: ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
- name: my-http-server
transport: http
url: http://localhost:8080
```
```
corvus batch targets.yaml --output-dir results/ --sarif --min-confidence 70
```
生成针对每个目标的 `report.json` 以及一个顶层的 `summary.md` 表格。
## 模块
34 个内置模块,涵盖完整的 OWASP MCP Top 10 以及协议、诱导、采样、OAuth 和供应链扩展:
### 静态模块(无实时工具调用)
| 名称 | OWASP | 测试内容 |
|------|-------|---------------|
| `tool-poisoning` | MCP03 | 工具描述中的隐藏指令、混淆和提示词注入模式 |
| `shadow-tool` | EXT03 | 指示危险操作的工具名称 —— 命名空间抢注、隐蔽链式调用、信任劫持 |
| `scope-audit` | MCP02 | 工具 inputSchema 中的凭据和 PII 字段 —— 请求密码、token 或 SSN 的工具 |
| `supply-chain` | MCP04 | 从 server 命令提取的已知易受攻击的 npm 包 (npm audit) |
| `supply-chain-python` | MCP04 | 从 server 环境提取的已知易受攻击的 Python 包 (pip list) |
| `osv-supply-chain` | MCP04 | 查询 OSV.dev API 以获取检测到的依赖项中的已知漏洞 |
| `github-advisory` | MCP04 | 查询 GitHub Security Advisories 以获取检测到的包中的已知漏洞 |
| `npm-behavior` | MCP04 | 查询 npm registry 以获取检测到的包中可疑的安装脚本 (postinstall, preinstall) |
| `auth-audit` | MCP07 | 暗示缺少、可选或可绕过身份验证的工具名称和描述 |
| `log-audit` | MCP08 | 暴露或篡改审计日志的工具 —— 反取证技术或运营数据泄露 |
| `schema-audit` | EXT02 | 扩大攻击面的弱 schema 定义(缺少必填字段、不受约束的类型) |
| `resource-uri` | EXT05 | 对 resources/list URI 的静态分析 —— 检测敏感 scheme(file://, env://, exec://) |
| `tool-chaining` | EXT03 | 检测隐蔽链式调用额外工具调用或绕过用户确认的工具描述 |
### 动态模块(实时工具调用)
| 名称 | OWASP | 测试内容 |
|------|-------|---------------|
| `cmd-injection` | MCP05 | 针对每个参数的命令、路径、SQL 和提示词注入 payload —— schema 感知,需确认 |
| `token-exposure` | MCP01 | 工具响应中泄露的凭据、文件系统路径、堆栈跟踪和 token |
| `ssrf` | EXT04 | 通过 URL/host 参数进行 SSRF —— 探测内部元数据 endpoint,测量时间异常 |
| `endpoint-probe` | MCP01 | 通过 resources/read 和 prompts/get 进行路径遍历、SSRF、模板注入和凭据暴露 |
| `param-smuggling` | EXT01 | 隐藏参数后门 —— 追加未声明的参数并测量行为差异 |
| `schema-bypass` | EXT01 | 工具是否正确拒绝违反其声明 schema 的输入 |
| `proto-fuzz` | EXT01 | 协议级崩溃测试 —— 未知方法、超长方法名、空 request ID |
| `batch-dos` | EXT01 | 发送 JSON-RPC 2.0 批量数组和超大 payload 以检测崩溃/DoS 条件 |
| `output-encoding` | MCP10 | 工具输出中的不可见 Unicode —— 控制字符、零宽字符、双向重写 (bidi overrides) |
| `response-flood` | MCP10 | 溢出 LLM 上下文窗口的过大或重复响应 |
| `response-injection` | MCP10 | 检测良性工具响应中注入的内容(HTML/JS/markdown 指令) |
| `rug-pull` | MCP06 | 动态测试后重新枚举 server;通过 diff 检测会话中途添加、删除或变异的工具 |
| `init-audit` | MCP07 | 审计 initialize 握手 —— serverInfo 注入字符、协议版本降级接受 |
| `oauth-bypass` | MCP07 | 测试 HTTP 传输 endpoint 的身份验证绕过:缺少身份验证、无效 Bearer、URL 内嵌凭据 |
| `sampling-probe` | EXT08 | 检测恶意 MCP sampling/createMessage —— 提示词注入、上下文泄露、未经请求的调用 |
| `elicitation-probe` | EXT09 | 检测 MCP elicitation/create 滥用 —— 凭据钓鱼、敏感数据 schema |
| `completion-probe` | EXT10 | 通过参数上下文探测 MCP completion/complete endpoint 的提示词注入 |
| `logging-probe` | EXT11 | 测试 server 是否允许未经身份验证的外部日志级别操作 |
| `prompts-injection` | EXT12 | 通过 MCP prompts/get 检测提示词注入 —— 静态模式 + 实时参数注入 |
| `cursor-probe` | EXT13 | 测试 MCP 分页游标处理是否存在路径遍历、超大值和注入 |
| `cancellation-probe` | EXT14 | 测试 MCP notifications/cancelled 处理是否存在竞争条件以及因未知 requestId 导致的崩溃 |
### 模块组
```
# 所有 modules(默认)
--module all
# 仅静态(不对 server 进行 live calls)
--module static
# 仅动态
--module dynamic
# 单个 module
--module cmd-injection
```
## 传输方式
### stdio
生成 server 进程并通过 stdin/stdout 进行通信。支持任何命令:
```
corvus scan --transport stdio --cmd "python server.py"
corvus scan --transport stdio --cmd "npx @modelcontextprotocol/server-filesystem /tmp"
corvus scan --transport stdio --cmd "uvx my-mcp-server --arg value"
```
### HTTP
连接到正在运行的 HTTP/SSE MCP server:
```
corvus scan --transport http --url http://localhost:8080
# 带有 auth
corvus scan --transport http --url http://localhost:8080 --header "Authorization: Bearer $TOKEN"
corvus scan --transport http --url http://localhost:8080 --header "X-API-Key: secret"
```
## 配置文件
创建 `corvus.toml` 以避免重复使用 CLI 标志:
```
[scan]
transport = "stdio"
cmd = "python my_server.py"
modules = "all"
timeout = 30
sarif = false
fail_on = "high"
[scan.headers]
"Authorization" = "Bearer my-token"
```
然后运行:
```
corvus scan --config corvus.toml
```
CLI 标志会覆盖配置文件中的值。`--config` 标志也支持绝对路径。
## CLI 参考
```
Usage: corvus scan [OPTIONS]
Scan an MCP server for security vulnerabilities.
Options:
-t, --transport TEXT stdio | http (overrides config)
--cmd TEXT Command to launch MCP server (stdio)
--url TEXT URL of MCP server (http)
-m, --module TEXT all | static | dynamic | (overrides config)
-o, --output-dir PATH
--fail-on TEXT Exit 1 if findings at this severity or above
(critical|high|medium|low)
--timeout INTEGER Request timeout in seconds (overrides config)
--sarif Also write SARIF 2.1.0 report
--header TEXT HTTP header "Key: Value" (repeatable, for http transport)
-c, --config PATH Path to corvus.toml config file
--plugin-dir TEXT Directory to load external modules from (repeatable)
--help Show this message and exit.
```
其他命令:
```
corvus list-modules # list available modules with OWASP ID and type
corvus list-modules --plugin-dir ./plugins/ # include external plugins
corvus version # print version
corvus init # generate a corvus.toml skeleton in the current directory
corvus report REPORT.json # regenerate MD/SARIF/HTML from an existing report.json
corvus diff OLD.sarif NEW.sarif # compare two SARIF files: new / fixed / unchanged findings
corvus score REPORT.json # print Risk Score (0-100) for a report
```
## 输出
每次扫描都会在 `corvus-sessions//` 下创建一个会话目录:
```
corvus-sessions/20260608-143022/
├── report.json # full structured result
├── report.md # human-readable with remediation guidance
└── report.sarif # SARIF 2.1.0 (only when --sarif is passed)
```
### SARIF 集成
SARIF 输出兼容 GitHub Advanced Security、VS Code SARIF Viewer 以及任何使用 SARIF 的 CI pipeline:
```
# GitHub Actions 示例
- name: Run Corvus
run: corvus scan --transport stdio --cmd "python server.py" --sarif --fail-on high
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: corvus-sessions/
```
## CI 集成
```
# 如果有任何 CRITICAL 发现则 Exit 1
corvus scan --transport stdio --cmd "python server.py" --fail-on critical
# 如果有任何 HIGH 或以上发现则 Exit 1
corvus scan --transport stdio --cmd "python server.py" --fail-on high
```
严重性级别(由低到高):`info` → `low` → `medium` → `high` → `critical`
## 插件系统
添加自定义模块而无需修改 Corvus 源码。
### 基于目录的插件
```
corvus scan --transport stdio --cmd "python server.py" --plugin-dir ./my-modules/
```
目录中的每个 `.py` 文件都会作为模块被加载。该文件必须定义一个继承自 `BaseModule` 的类:
```
from corvus.modules.base import BaseModule, Finding, Severity
class MyCustomModule(BaseModule):
name = "my-check"
owasp_id = "MCP-CUSTOM"
module_type = "static"
description = "Custom check for my organization"
async def run(self, surface, transport):
findings = []
for tool in surface.tools:
if "dangerous_pattern" in tool.description:
findings.append(Finding(
rule_id="MY001",
tool_name=tool.name,
severity=Severity.HIGH,
title="Dangerous pattern detected",
description=f"Tool '{tool.name}' contains a dangerous pattern.",
remediation="Remove or sanitize the pattern.",
))
return findings
```
### 基于包的插件
通过 `pyproject.toml` 的 entry points 注册:
```
[project.entry-points."corvus.modules"]
my-check = "my_package.modules.my_check:MyCustomModule"
```
在 `pip install my-package` 之后,Corvus 会自动发现该模块。
## 研究:MCP 生态系统安全审计
Corvus 已在真实的 MCP 生态系统中通过 17 个案例研究进行了实战测试 —— 审计了 397 个 server,涵盖官方的 `@modelcontextprotocol` 包、社区 server 以及更广泛的 npm 和 PyPI 生态系统。
| 指标 | 总计(17 个案例研究) |
|--------|-------------------------------|
| 审计的 server 数量 | **397** |
| 原始发现 | **~5566** |
| 真阳性 | **~1325** |
来自真实环境的关键发现:
- **100% 被测试的 MCP server 在遇到带有未知 requestId 的 37 字节 notifications/cancelled payload 时发生崩溃 (EXT14) —— 零身份验证即可实现的普遍 DoS**
- **37% 的 server 在遇到符合规范的 JSON-RPC 批量数组或超大的方法名时崩溃 —— 无需身份验证即可复现的 DoS**
- **71% 的 server 在 initialize 握手期间接受任意的 protocolVersion 字符串 —— 接受协议降级**
- **3 个 server (myclaw-toolkit, @sap-ux/fiori-mcp-server, markitdown-mcp) 确认存在 SSRF —— 可从工具参数访问内部元数据 endpoint**
- **供应链级联:@modelcontextprotocol/sdk ≤1.25.1 安全公告影响生态系统中的大多数基于 JS 的 server**
- **通过 5 次校准迭代,误报率从 ~40% (v0.5.0,早期校准) 降至 ~7% (CS03,v1.0.1)**
- **CS04 引入了 3 种新的系统性误报模式:docs server 懒加载 (MCP06,来自 sveltejs 的 195 个误报),Python strptime 错误反射 (MCP05,33 个误报),以及第三方 API 错误消息回显 (MCP05,11 个 server 中 62+ 个误报)**
- **发现新的攻击模式:SaaS 描述变异 rug-pull —— mcp-devutils 在会话期间根据计费逻辑将 29 个工具描述从 '[PRO — trial]' 更改为 '[PRO — trial expired]'**
- **通过 MCP 范围蔓延进行隐蔽 AI 代理监控:clarvia-mcp-server 指示代理“在每次工具调用后使用”以将所有活动报告给外部 server**
- **带有时间证据的 SSRF:pulsemcp-pulse-fetch scrape.url 访问 169.254.169.254 AWS 元数据 endpoint(相比 2.3s 基线有 8.3s 的时间差)**
- **存储型 SQL 注入模式:arxiv-mcp-server watch_topic.topic 将 SQL payload 存储在数据库中而未进行净化(极有可能,需要 check_alerts 验证)**
- **反取证日志清除:godot-mcp-server 暴露了 clear_console_log 工具(严重,MCP08)—— 结合 save_resource_to_file/take_screenshot 中的写入路径遍历,构成了“泄露后掩盖踪迹”的攻击链**
- **在各生态系统中确认了 XSS 响应注入模式:functype-mcp-server (npm) 和 awslabs.amazon-kendra-index-mcp-server (PyPI) 都在错误消息中原样反映了未经净化的 XSS payload —— 系统性的跨 SDK 问题**
完整的数据集、精选发现和方法论请见 [`case-studies/`](case-studies/)。
### 负责任的披露
在 17 个案例研究中提交了 56 份安全公告 —— 7 份已发布,49 份正在进行积极的协调披露(90 天窗口期)。
**已发布:**
| 公告 | 包 | 严重程度 | 发现 |
|----------|---------|----------|---------|
| [GHSA-43j9-hmpq-cgv7](https://github.com/advisories/GHSA-43j9-hmpq-cgv7) | remnux-mcp-server | MEDIUM | 在非本地环回部署上通过 HTTP 传输实现的未经身份验证的 RCE |
| [GHSA-hv3x-m9fv-4vhf](https://github.com/advisories/GHSA-hv3x-m9fv-4vhf) | mcp-server-git | HIGH | 通过符合规范的 JSON-RPC 批量数组和超大方法名实现的 DoS |
| [GHSA-3f55-qgq4-f88c](https://github.com/advisories/GHSA-3f55-qgq4-f88c) | server-sequential-thinking | MEDIUM | 通过超大 JSON-RPC 方法名实现的 DoS (CWE-755) |
| [GHSA-jgxf-j67w-w284](https://github.com/advisories/GHSA-jgxf-j67w-w284) | campertunity-ai-tools | HIGH | 通过预订 API URL 参数实现的 SSRF —— 内部元数据 endpoint 可访问 |
| [GHSA-prc4-649r-564g](https://github.com/advisories/GHSA-prc4-649r-564g) | localparse-mcp | HIGH | 在 parse_url 中确认存在 SSRF —— 时间和超时信号已确认 (CWE-918) |
| [GHSA-32vx-mq6h-p8f3](https://github.com/advisories/GHSA-32vx-mq6h-p8f3) | emilia-protocol | HIGH | 通过 trust_decision/receipt_quality_check + 强制合规网关实现的提示词模板注入EXT03/EXT12) |
| [GHSA-wx78-8jx3-wcv9](https://github.com/advisories/GHSA-wx78-8jx3-wcv9) | @tensorfeed/mcp-server | HIGH | 跨越 6 个工具的 XSS 反射集群 —— 原样回显未净化的 payload (MCP05) |
**积极的协调披露(49 份公告):** 包含的包有 @playwright/mcp, mcp-server-sqlite, mcp-shell-server, myclaw-toolkit(严重), @sap-ux/fiori-mcp-server 及其他 —— 90 天禁发窗口期正在进行中。
完整公告索引:[`case-studies/DISCLOSURE-PROCESS.md`](case-studies/DISCLOSURE-PROCESS.md)
## 常见问题
**Corvus 与 mcp-scan / Snyk Agent Scan 相比如何?**
[mcp-scan](https://github.com/invariantlabs-ai/mcp-scan)(于 2025 年被 Snyk 收购,现为 [Snyk Agent Scan](https://github.com/snyk/agent-scan))是部署最广泛的 MCP 安全工具,在提示词注入和工具投毒方面表现出色。如果这是您的主要关注点,两者都值得运行。
这些工具从不同角度处理 MCP 安全性:
| | mcp-scan / Snyk Agent Scan | Corvus |
|---|---|---|
| **范围** | 提示词注入、工具投毒、有毒流、跨源提权 | 完整的 [OWASP MCP Top 10](https://owasp.org/www-project-top-10-for-large-language-model-applications/) —— 34 个模块 |
| **视角** | 客户端:读取您的 MCP 配置文件 | 服务端:通过 stdio 或 HTTP 直接连接 |
| **探测** | 静态分析 + 可选的代理监控 | 静态分析 + 实时动态探测(带 payload 的实际工具调用) |
| **CI/CD** | 基础 | SARIF 输出,`--fail-on high`,批量扫描 |
| **覆盖范围** | 专注于提示词注入 / 投毒 | 增加了命令注入、SSRF、身份验证绕过、供应链、schema 绕过、参数走私、DoS、OAuth、采样/诱导滥用 |
| **实时** | ✅ 用于实时监控的代理模式 | ❌ 仅限单点时间扫描 |
| **披露** | 无公开公告计划 | 已提交 50 份协调的 GHSA |
| **支持** | Snyk(企业级) | 独立,专注于安全研究 |
**何时使用 mcp-scan:** 您希望对代理流量进行实时代理监控,或者您需要 Snyk 企业级集成。
**何时使用 Corvus:** 您正在进行全面的安全审计,需要兼容 CI/CD 的输出,或者希望测试提示词注入之外的攻击面(命令注入、SSRF、身份验证绕过、供应链等)。
它们是互补的 —— mcp-scan 擅长运行时监控,Corvus 擅长单点时间的深度检测。
## 开发
```
git clone https://github.com/CobaltoSec/corvus
cd corvus
pip install -e ".[dev]"
pytest
```
## 许可证
MIT
标签:AI安全, Chat Copilot, CISA项目, LNA, MCP, Python, 云安全监控, 安全测试, 攻击性安全, 文档结构分析, 无后门, 无服务器架构, 逆向工具, 静态分析