x0base/mcp-security-toolkit
GitHub: x0base/mcp-security-toolkit
一个面向AI代理和MCP服务器的原子化安全审计工具包,用于源代码审计和渗透测试。
Stars: 0 | Forks: 0
# mcp 安全工具包
[](https://github.com/x0base/mcp-security-toolkit/actions/workflows/ci.yml)
[](https://pypi.org/project/mcp-security-toolkit/)
[](https://pypi.org/project/mcp-security-toolkit/)
[](LICENSE)
**面向代理构建者的源代码、schema 与提示词审计原语。**
可插入 Claude Code / Cursor / Claude Desktop。在您已使用的编码代理中本地审计 MCP 服务器、代理
工具 schema、系统提示词、JWT 以及 HTTP 响应差异。原子化、可审计,无需编排。
## 为什么存在此工具包
大多数安全类 MCP 服务器封装了现有的 CLI 工具(Burp、Shodan、CyberChef),或用于审计 MCP 配置和工具描述。当开发者在代码中集成 LLM 功能时,真正需要的原语——如对 MCP 服务器的源代码级审计、对代理工具的 schema 级审计、对系统提示词的静态审查——却鲜少涉及。
`mcp-security-toolkit` 提供了这些原语,以及代理在 AppSec 工作中常用的渗透测试原子工具,因此您只需运行一个服务器,而非五个。
## 核心工具
### `mcp_server_audit`
对 MCP 服务器的 Python 源代码进行启发式 AST 审计。枚举
`@tool` 装饰的工具和命令式注册的工具,然后运行 13 个检测器:
| 检测器 | 类别 | 严重性 |
|---|---|---|
| Shell 执行 | `shell-exec` | 高 |
| 文件系统写入/删除 | `fs-write` / `fs-destructive` | 中-高 |
| 网络出站 | `network-egress` | 中 |
| 代码注入 | `code-injection` | 高 |
| 过于宽泛的参数 | `over-broad-param` | 中 |
| 模糊/缺失的文档字符串 | `ambiguous-description` | 低-中 |
| 从环境变量读取密钥 | `secret-in-env` | 信息 |
| 路径遍历 | `path-traversal` | 高 |
| 文档字符串中的提示词注入 | `tool-description-injection` | 中 |
| 通过 URL 参数的 SSRF | `ssrf` | 高 |
| Resource URI → SQL 注入 | `mcp-resource-uri-sqli` | 高 |
| 工具覆盖(跨工具) | `tool-shadowing` | 中 |
追踪 `from X import Y [as Z]` 别名,确保重命名的危险导入不会被遗漏。报告包含 `coverage.detectors_run` 列表和 `limitations`——未发现漏洞 **不** 代表安全。
是对 Snyk / Invariant Labs `mcp-scan`(审计 MCP 配置和工具描述)的补充,本工具审计的是服务器的*源代码*。
### `agent_tool_risk_audit`
接收单个代理工具的 JSON schema 并报告 schema 级风险:
过于宽泛的参数、模糊的描述、缺失的约束、数据外泄风险、危险的默认值。
### `prompt_injection_audit`
静态审查系统提示词 / 模板的注入攻击面。
标记不受信任的占位符、缺失的定界符、信任边界违规、危险指令模式。
### `owasp_llm_classify`
将发现或观察结果映射到 OWASP LLM Top 10 (2025),附带推理和严重性。适用于报告和工单创建。
### `http_diff`
专注于 AppSec 的两个 HTTP 响应差异比对。用于手动的认证绕过 / IDOR 分诊。
高亮显示设置/添加/删除的响应头、状态码变化、正文差异以及与安全相关的 Cookie。
### `jwt_inspect`
解码并审计 JWT。标记 `alg:none`、弱 HS 密钥(小型字典检查)、过期时间、缺失的标准声明、可疑的 `kid`(路径遍历)以及外部密钥 URL(`jku`、`x5u`)。
## 渗透测试包(原子原语)
捆绑在一起,以便代理无需安装五个 MCP 即可获得基础知识。每个工具都是一个输入 → 一个输出,无需链式调用。
- `default_creds_lookup` — 按供应商/产品查找已知默认凭据(50 多个产品,别名如 `fortigate`、`idrac`、`wp`)
- `sensitive_files_list` — 按技术栈整理的敏感路径(`common`、`php`、`wordpress`、`dotnet`、`java`、`node`、`python`、`k8s`、`docker`、`ci`);仅返回路径,不进行探测
- `wordlist_gen` — 基于 OSINT 的字典生成器(`passwords` / `usernames` / `subdomains` 模式)
- `graphql_introspect` — 单次内省 POST 请求 → schema 摘要 + 安全观察
- `phpggc_generate` — 封装 `phpggc` CLI,用于生成 PHP 反序列化 gadget 链(若二进制文件缺失则优雅处理)
- `interactsh_register` / `interactsh_poll` / `interactsh_stop` — 封装 `interactsh-client` CLI,用于捕获带外回调 URL(盲注 SSRF / XXE / RCE 确认)。`_stop` 终止并清理会话;每次注册时运行 TTL 垃圾回收
## 示例输出
来自三个核心工具的真实输出。点击展开。
```
{
"file": "sample_mcp_server.py",
"tools_found": 4,
"summary": {"high": 1, "medium": 5, "low": 1, "info": 1},
"tools": [
{ "name": "safe_echo", "findings": [] },
{
"name": "run_cmd",
"findings": [
{"category": "ambiguous-description", "severity": "low",
"message": "docstring is very short (4 chars) — risk of LLM misuse"},
{"category": "over-broad-param", "severity": "medium",
"message": "parameter `cmd`: command-like parameter typed as bare `str`"},
{"category": "shell-exec", "severity": "high",
"message": "calls `subprocess.run`"}
]
},
{
"name": "read_anything",
"findings": [
{"category": "ambiguous-description", "severity": "medium",
"message": "tool has no docstring — the LLM cannot reason about when to use it"},
{"category": "over-broad-param", "severity": "medium",
"message": "parameter `path`: path-like parameter typed as bare `str` (no allow-list)"}
]
},
{
"name": "write_log",
"findings": [
{"category": "over-broad-param", "severity": "medium",
"message": "parameter `path`: path-like parameter typed as bare `str` (no allow-list)"},
{"category": "fs-write", "severity": "medium",
"message": "opens file for writing (mode='a')"}
]
}
],
"file_level_findings": [
{"category": "secret-in-env", "severity": "info",
"message": "reads secret from env `SECRET_API_KEY` — ensure it is documented in README and never logged"}
]
}
```
```
{
"tool_name": "shell_exec",
"detected_format": "mcp",
"findings": [
{"category": "ambiguous-description", "severity": "medium", "path": "",
"message": "description is very short (5 chars) — high risk of LLM misuse"},
{"category": "risky-name-vague-desc", "severity": "medium", "path": "",
"message": "tool name suggests it executes ('exec') but description is brief — agent may misuse"},
{"category": "over-broad-param", "severity": "high", "path": "cmd",
"message": "command-like param `cmd` is bare string — agent can execute arbitrary commands"},
{"category": "over-broad-param", "severity": "high", "path": "url",
"message": "url-like param `url` is bare string with no `pattern` — agent can reach arbitrary hosts (SSRF / exfil)"},
{"category": "dangerous-default", "severity": "medium", "path": "verify_ssl",
"message": "safety-related param `verify_ssl` defaults to `False` — disables a safeguard by default"},
{"category": "exfil-shape", "severity": "medium", "path": "",
"message": "tool accepts both a URL-like destination and a data-like payload — classic exfil shape"}
]
}
```
```
{
"valid_structure": true,
"header": {"alg": "HS256", "typ": "JWT"},
"payload": {"sub": "1234567890", "name": "John Doe", "iat": 1516239022},
"weak_secret": "your-256-bit-secret",
"findings": [
{"category": "missing-claim", "severity": "medium",
"message": "no `exp` claim — token never expires"},
{"category": "missing-claim", "severity": "low", "message": "no `iss` claim"},
{"category": "missing-claim", "severity": "low", "message": "no `aud` claim"},
{"category": "weak-secret", "severity": "high",
"message": "signature verifies with common weak secret: 'your-256-bit-secret'"}
]
}
```
## 推荐搭配的 MCP 服务器
为了在相关领域获得更深度的覆盖,我们明确推荐(且不重复实现)以下工具:
- [PortSwigger/mcp-server](https://github.com/PortSwigger/mcp-server) — Burp Suite
- [ChromeDevTools/chrome-devtools-mcp](https://github.com/ChromeDevTools/chrome-devtools-mcp) — Chrome DevTools
- [invariantlabs-ai/mcp-scan](https://github.com/invariantlabs-ai/mcp-scan) — MCP 配置 / 工具描述审计(与我们源代码级审计互补)
- [mukul975/cve-mcp-server](https://github.com/mukul975/cve-mcp-server) — 完整的 27 工具 CVE 情报服务器
## 安装
```
pip install mcp-security-toolkit
```
```
{
"mcpServers": {
"sec": { "command": "mcp-security-toolkit" }
}
}
```
## 本地开发
```
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest
ruff check .
```
端到端 MCP 冒烟测试(通过 stdio 启动服务器,列出工具,调用其中两个):
```
python scripts/smoke_mcp.py
```
## 防御性助手 — 修复我们检测到的问题
上述工具用于**发现** MCP 服务器中的不安全模式。而 [`mcp_security_toolkit.helpers`](./src/mcp_security_toolkit/helpers/) 包则相反:它是一组即插即用的原语,MCP 作者可以导入它们来使其工具在构造上就是安全的。
```
from mcp_security_toolkit.helpers import (
safe_path, safe_filename, safe_url, safe_sql_identifier, evaluate_expression,
)
@mcp.tool()
def read_log(name: str) -> str:
p = safe_path(name, root="/var/log/myapp", must_exist=True)
return p.read_text()
@mcp.tool()
def save_upload(filename: str, data: bytes) -> str:
name = safe_filename(filename) # basename-only
(Path("/var/uploads") / name).write_bytes(data)
return name
@mcp.tool()
def fetch_url(url: str) -> str:
url = safe_url(url) # blocks SSRF
return httpx.get(url, timeout=5).text
ALLOWED_TABLES = {"users", "orders", "events"}
@mcp.tool()
def count_rows(table: str) -> int:
table = safe_sql_identifier(table, allow=ALLOWED_TABLES)
return db.execute(f"SELECT COUNT(*) FROM {table}").scalar()
@mcp.tool()
def evaluate_formula(expr: str, price: float, qty: int) -> float:
return evaluate_expression(expr, variables={"price": price, "qty": qty})
```
纯函数,无 I/O,无全局状态。每个函数都能在一行内修复 `mcp_server_audit` 对应的发现类别。
## GitHub Action
将其添加到任何仓库,以在 CI 中运行 `mcp_server_audit`,将 SARIF 上传到安全选项卡,并在达到配置的严重性级别时使构建失败:
```
# .github/workflows/mcp-audit.yml
on: [push, pull_request]
jobs:
audit:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v5
- uses: x0base/mcp-security-toolkit@v0.3
with:
path: src/my_mcp_server.py
fail-on-severity: high
```
## CLI
```
# 默认(无参数):启动 MCP stdio 服务器 —— 即您的客户端配置所调用的内容
mcp-security-toolkit
# 审核您本地 Claude / Cursor / Claude Desktop 配置启动的每一个 MCP 服务器
mcp-security-toolkit scan-installed
mcp-security-toolkit scan-installed --sarif > findings.sarif
# 零安装运行,通过 uv
uvx mcp-security-toolkit scan-installed
```
## 将工具输出视为不可信数据
部分工具返回的内容可能来自攻击者控制的源:`http_diff` 会引用目标响应体,`interactsh_poll` 返回原始的带外请求,`graphql_introspect` 返回目标控制的 schema 名称。如果此类字符串包含“忽略之前的指令...”等内容,读取它的 LLM 代理可能会遵循内嵌的指令——这是典型的间接提示词注入。MCP 客户端应在定界符(如 `...`)内渲染工具输出,而不是将其静默地流入下一个提示词。
参见 [THREAT_MODEL.md](./THREAT_MODEL.md#tool-outputs-are-untrusted-data)。
## 非目标
- 不进行跨工具的编排、链接或决策逻辑——仅提供原语。
- 不重新实现功能齐全的攻击性 CLI 工具(`sqlmap`、`ghauri`、`dalfox`);当封装小型、专注的 CLI 是自然选择时(`phpggc`、`interactsh-client`),我们会直接封装,并提供优雅的“二进制文件未找到”路径。
- 不进行新颖的攻击性研究——所有引用的技术均来自公开来源。
## 许可证
MIT。
mcp_server_audit 作用于一个故意设计糟糕的测试文件 — 发现了 subprocess.run 的 shell 执行、过于宽泛的 path: str 参数、缺失的文档字符串、文件系统写入以及从环境变量读取密钥。
```
{
"file": "sample_mcp_server.py",
"tools_found": 4,
"summary": {"high": 1, "medium": 5, "low": 1, "info": 1},
"tools": [
{ "name": "safe_echo", "findings": [] },
{
"name": "run_cmd",
"findings": [
{"category": "ambiguous-description", "severity": "low",
"message": "docstring is very short (4 chars) — risk of LLM misuse"},
{"category": "over-broad-param", "severity": "medium",
"message": "parameter `cmd`: command-like parameter typed as bare `str`"},
{"category": "shell-exec", "severity": "high",
"message": "calls `subprocess.run`"}
]
},
{
"name": "read_anything",
"findings": [
{"category": "ambiguous-description", "severity": "medium",
"message": "tool has no docstring — the LLM cannot reason about when to use it"},
{"category": "over-broad-param", "severity": "medium",
"message": "parameter `path`: path-like parameter typed as bare `str` (no allow-list)"}
]
},
{
"name": "write_log",
"findings": [
{"category": "over-broad-param", "severity": "medium",
"message": "parameter `path`: path-like parameter typed as bare `str` (no allow-list)"},
{"category": "fs-write", "severity": "medium",
"message": "opens file for writing (mode='a')"}
]
}
],
"file_level_findings": [
{"category": "secret-in-env", "severity": "info",
"message": "reads secret from env `SECRET_API_KEY` — ensure it is documented in README and never logged"}
]
}
```
agent_tool_risk_audit 作用于一个工具 schema,其中包含裸字符串 cmd / url、一个 URL+数据外泄形状,以及 verify_ssl: false。
```
{
"tool_name": "shell_exec",
"detected_format": "mcp",
"findings": [
{"category": "ambiguous-description", "severity": "medium", "path": "jwt_inspect 作用于众所周知的 jwt.io 默认令牌 — 使用小型弱密钥字典验证签名,发现缺失的声明。
```
{
"valid_structure": true,
"header": {"alg": "HS256", "typ": "JWT"},
"payload": {"sub": "1234567890", "name": "John Doe", "iat": 1516239022},
"weak_secret": "your-256-bit-secret",
"findings": [
{"category": "missing-claim", "severity": "medium",
"message": "no `exp` claim — token never expires"},
{"category": "missing-claim", "severity": "low", "message": "no `iss` claim"},
{"category": "missing-claim", "severity": "low", "message": "no `aud` claim"},
{"category": "weak-secret", "severity": "high",
"message": "signature verifies with common weak secret: 'your-256-bit-secret'"}
]
}
```
标签:AI安全, AI模型安全, AST审计, Chat Copilot, Claude集成, HTTP响应分析, JWT审计, MCP安全, MCP服务器审计, OWASP LLM Top 10, Prompt注入检测, 云安全监控, 代码生成, 凭证嗅探, 原子工具, 安全工具包, 安全最佳实践, 安全检测器, 安全测试, 工具审计, 提示审计, 攻击性安全, 模式审计, 渗透测试工具, 源代码分析, 系统提示安全, 逆向工具, 静态分析