miloudbelarebia/mcp-rampart

GitHub: miloudbelarebia/mcp-rampart

针对 FastAPI 应用暴露为 MCP 服务器的场景,提供预启动路由安全审计与运行时 prompt 注入防护的嵌入式安全工具包。

Stars: 1 | Forks: 0

🛡️ mcp-rampart

针对作为 MCP 服务器暴露的 FastAPI 应用的安全防御工事。
起飞前审计。运行时 prompt 注入护栏。一个包搞定。

PyPI License Stars

``` from fastapi import FastAPI from mcp_rampart import MCPRampart app = FastAPI() # ... 你现有的路由 ... rampart = MCPRampart(app) # 1. Speak MCP. report = rampart.audit() # 2. Audit what you'd expose. if report.has_blockers(): report.print_text(); raise SystemExit(1) rampart.enable_guardrails(policy="block") # 3. Block prompt-injection at runtime. ``` ## MCP 安全的 4 个层级 MCP 在 2026 年从“实验性技术”迅速发展到**每月超过 9700 万次安装**。安全工具直到最近才跟上步伐,而且其中大多数解决的问题与您面临的并不相同。以下是全景图: ``` ┌─────────────────────────────────────────────────────────────────┐ │ Layer 1 — The LLM itself (Claude, GPT, Gemini) │ │ Worry: hallucination, jailbreaks at the model level │ │ → out of scope for everyone — model provider's problem │ └──────────────────────┬──────────────────────────────────────────┘ │ ▼ (JSON-RPC over MCP transport) ┌─────────────────────────────────────────────────────────────────┐ │ Layer 2 — The MCP CLIENT (Claude Desktop, Cursor, agents) │ │ Worry: the LLM calls something risky or exfiltrates data │ │ Tools: pipelock, mcp-firewall, SecretiveShell/MCP-Bridge │ └──────────────────────┬──────────────────────────────────────────┘ │ ▼ (HTTP / SSE) ┌─────────────────────────────────────────────────────────────────┐ │ Layer 3 — The GATEWAY / proxy in front of the MCP server │ │ Worry: who's allowed to talk to this server, with what auth │ │ Tools: apache/casbin-gateway, hyprmcp/mcp-gateway │ └──────────────────────┬──────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Layer 4 — The MCP SERVER itself ← 🛡️ mcp-rampart │ │ Worry: did I expose dangerous routes? is an injection hiding │ │ inside the arguments of every tools/call? │ │ Tools: mcp-rampart (this project) │ └──────────────────────┬──────────────────────────────────────────┘ │ ▼ (which servers are even installed?) ┌─────────────────────────────────────────────────────────────────┐ │ Layer 5 — The USER's MCP config (~/.mcp.json, etc.) │ │ Worry: am I installing a malicious server on my machine │ │ Tools: apisec-inc/mcp-audit, ModelContextProtocol-Security/ │ │ mcpserver-audit │ └─────────────────────────────────────────────────────────────────┘ ``` | 层级 | 它回答的问题 | 代表性工具 | |--:|---|---| | 1 | “模型本身安全吗?” | (模型提供商) | | 2 | “我的 agent 是否在泄露信息或调用有风险的内容?” | [pipelock](https://github.com/luckyPipewrench/pipelock) (583⭐) | | 3 | “谁被允许与我的服务器对话,使用什么身份验证?” | [casbin-gateway](https://github.com/apache/casbin-gateway) (559⭐), [hyprmcp/mcp-gateway](https://github.com/hyprmcp/mcp-gateway) (92⭐) | | **4** | **“我是不是刚把管理端点的访问权限交给了语言模型?是否有注入内容正悄悄混入每次调用的参数中?”** | **mcp-rampart** | | 5 | “我正在安装的这个 MCP 服务器真的安全吗?” | [apisec mcp-audit](https://github.com/apisec-inc/mcp-audit) (149⭐), [mcpserver-audit](https://github.com/ModelContextProtocol-Security/mcpserver-audit) (16⭐) | **您可能需要不止一个层级。** mcp-rampart 是唯一一个在第 4 层运行的库——该层级解决的是 *MCP 服务器作者* 的问题,而不是运维人员或用户的问题。 ## 为什么是“框架感知”,而不是“MCP 通用” 您会注意到第 2、3 和 5 层的每个工具都是**框架无关的**——它们拦截传输流(HTTP、JSON-RPC、配置文件),而不关心其背后运行的是什么。这对它们来说行得通,因为它们不需要关心。 mcp-rampart **需要**看透背后。起飞前审计根本无法作为代理存在: | mcp-rampart 能看到什么 | 原因(它被安装 *在* 应用内部) | |---|---| | `@app.get("/api/admin/users/...")` 装饰器 | 直接读取 `app.routes` | | 声明了 `email`、`phone`、`ssn` 的 Pydantic 响应模型 | 内省 `route.response_model` | | 工具处理程序上缺失 docstring | 读取 `route.endpoint.__doc__` | | 回退到 `str` 的未类型化参数 | 读取 `inspect.signature(handler)` | | 看起来像 `/auth/`、`/oauth/`、`/internal/` 的路径模式 | 对 `route.path` 进行模式匹配 | 第 3 层的代理只能看到 `POST /mcp {"method":"tools/call","name":"delete_user","args":{...}}`。它**看**不到上游的 `@app.delete("/api/admin/users/{user_id}")`。因此,它无法告诉您“您即将将管理接口暴露给 LLM”——它只能告诉您“有人刚刚调用了 delete_user”。 代价是:mcp-rampart 目前**仅支持 FastAPI**。我们现阶段是有意付出这个代价的,因为深度内省正是审计的价值所在。Node.js 和 Flask/Django 已被列入下一步的发展路线图。 ## mcp-rampart 的独特定位 以下是 mcp-rampart 成为唯一 ✅ 的五个具体维度: | | mcp-rampart | pipelock | casbin-gw | apisec mcp-audit | hyprmcp | |---|:--:|:--:|:--:|:--:|:--:| | **在您的 FastAPI 应用内部运行**(无需额外进程) | ✅ | ❌ | ❌ | ❌ | ❌ | | 审计 **您即将暴露的路由**(而不是别人的) | ✅ | ❌ | ❌ | ❌ | ❌ | | 遇到 **CRITICAL**(严重)发现时拒绝启动服务器 | ✅ | ❌ | ❌ | ❌ | ❌ | | 在每次 `tools/call` 时进行 **Prompt 注入** 检测 | ✅ | 部分 | ❌ | ❌ | ❌ | | 三种策略模型(`block` / `alert` / `log`)+ 可插拔的 callback | ✅ | ❌ | ❌ | ❌ | ❌ | 不同的形态,不同的问题,不同的代价。 ## 快速开始 ``` pip install mcp-rampart ``` ``` from fastapi import FastAPI from mcp_rampart import MCPRampart app = FastAPI(title="My App") @app.get("/api/users/{user_id}") async def get_user(user_id: int): """Get a user by their ID.""" return {"id": user_id, "name": "Alice"} rampart = MCPRampart(app) # auto-discovers routes, mounts /mcp print(rampart.summary()) # 预检审计 — 遇到 CRITICAL 发现时拒绝启动服务器 report = rampart.audit() report.print_text() if report.has_blockers(): raise SystemExit(1) # Runtime guardrail — 扫描每一个传入的 tools/call rampart.enable_guardrails(policy="block") ``` 您的应用现在将暴露: - `GET /mcp` — 服务器信息和工具列表 - `POST /mcp` — MCP JSON-RPC 端点(Streamable HTTP 传输) 任何 MCP 客户端(Claude Desktop、ChatGPT、Gemini、Cursor、Codex)都可以连接。 ## 起飞前审计详解 `rampart.audit()` 会遍历每个暴露的工具并运行 **7 项检查**。每个发现都会获得一个严重性标签、一个建议以及一个您可以在 CI 中进行匹配的类别代码。 | 严重性 | 检查项 | 触发条件... | |---|---|---| | 🔴 CRITICAL | `EXPOSED_AUTH` | 路由路径匹配 `/auth/`、`/login`、`/token`、`/oauth` 等 | | 🔴 CRITICAL | `EXPOSED_ADMIN` | 路由路径匹配 `/admin/`、`/internal/`、`/debug/` 等 | | 🟠 HIGH | `MISSING_DOCSTRING` | 没有描述 → LLM 将靠猜测并调用错误的工具 | | 🟠 HIGH | `SENSITIVE_PARAM_NAME` | 参数名包含 `password`、`token`、`api_key` 等 | | 🟠 HIGH | `PII_IN_RESPONSE` | 响应 schema 声明了如 `email`、`phone`、`ssn` 等字段 | | 🟡 MEDIUM | `DESTRUCTIVE_METHOD` | 暴露了 `DELETE` / `PUT` / `PATCH` 且没有显式确认流程 | | 🔵 LOW | `UNTYPED_PARAMETER` | 3 个或更多参数回退到 `str` 类型 —— LLM 可能发送格式错误的输入 | 在一个故意留有缺陷的应用上的示例输出: ``` 🛡️ MCPRampart audit report 13 tools from 13 routes 🔴 2 critical · 🟠 4 high · 🟡 3 medium · 🔵 1 low 🔴 [CRITICAL] POST /api/auth/login Authentication endpoint exposed to LLM clients ↳ Add '/api/auth/login' to exclude_paths 🔴 [CRITICAL] DELETE /api/admin/users/{user_id} Admin / internal endpoint exposed to LLM clients ↳ Exclude this route from MCP exposure 🟠 [HIGH] GET /api/users/me Response may leak PII fields: email, phone, address … ``` 在 CI 中使用: ``` - run: python -c "from myapp import rampart; r = rampart.audit(); r.print_text(); exit(1 if r.has_blockers() else 0)" ``` ## 运行时护栏详解 审计在启动时进行一次。**而护栏将永远运行——在每次 `tools/call` 请求上。** 它会根据精选的 prompt 注入模式目录,递归扫描调用的 `arguments`(在字典和列表中): | 置信度 | 会被拦截的内容 | |---|---| | 🔴 HIGH | `ignore previous instructions`、`you are now …`、`developer/admin/jailbreak mode`、聊天模板控制 token(`<\|im_start\|>`)、`[[system]]` 标记、`SYSTEM: do …` | | 🟠 MEDIUM | `system prompt`、`act as …`、`pretend to be …`、“reveal your instructions”、“repeat everything above”、“begin new session as” | | 🔵 LOW | 数据窃取动词(`send your tokens to …`)、`