x0base/mcp-security-toolkit

GitHub: x0base/mcp-security-toolkit

一个面向AI代理和MCP服务器的原子化安全审计工具包,用于源代码审计和渗透测试。

Stars: 0 | Forks: 0

# mcp 安全工具包 [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/aee0bd460b093413.svg)](https://github.com/x0base/mcp-security-toolkit/actions/workflows/ci.yml) [![PyPI](https://img.shields.io/pypi/v/mcp-security-toolkit.svg)](https://pypi.org/project/mcp-security-toolkit/) [![Python](https://img.shields.io/pypi/pyversions/mcp-security-toolkit.svg)](https://pypi.org/project/mcp-security-toolkit/) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](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 垃圾回收 ## 示例输出 来自三个核心工具的真实输出。点击展开。
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": "", "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"} ] } ```
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'"} ] } ```
## 推荐搭配的 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。
标签:AI安全, AI模型安全, AST审计, Chat Copilot, Claude集成, HTTP响应分析, JWT审计, MCP安全, MCP服务器审计, OWASP LLM Top 10, Prompt注入检测, 云安全监控, 代码生成, 凭证嗅探, 原子工具, 安全工具包, 安全最佳实践, 安全检测器, 安全测试, 工具审计, 提示审计, 攻击性安全, 模式审计, 渗透测试工具, 源代码分析, 系统提示安全, 逆向工具, 静态分析