csinexus/mcpshield

GitHub: csinexus/mcpshield

针对未修复的 MCP STDIO 命令注入漏洞提供直接替代防护方案的 Python 安全工具。

Stars: 0 | Forks: 0

# mcpshield ![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue) [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE) 针对未修复的 MCP STDIO 命令注入漏洞的直接替代解决方案 (即 CVE-2026-30623 系列漏洞,于 2026 年 4 月被 OX Security 披露为“按 设计如此”——不会有 SDK 补丁)。只需导入一行代码,你的 Python 应用启动的每一个 stdio MCP server,都会在操作系统生成进程之前,对其 command/args/env 进行验证。 如果你是初次了解,请先阅读[范围](#scope),然后通过[安装](#install) 和[快速入门](#getting-started),在两分钟内获得保护。 ## 目录 - [项目状态](#project-status) - [范围](#scope) - [安装](#install) - [快速入门](#getting-started) - [选项 A:自动补丁(Python MCP 主机)](#option-a-the-autopatch-python-mcp-hosts) - [选项 B:静态检查(任意语言,零执行)](#option-b-static-check-any-language-zero-execution) - [选项 C:启动监督器(非 Python 主机)](#option-c-launch-supervisor-non-python-hosts) - [拦截与警告的对比](#what-gets-blocked-vs-what-gets-a-warning) - [逃生舱](#the-escape-hatches) - [CLI 参考](#cli-reference) - [已知限制](#known-limitations) - [项目布局](#project-layout) - [开发](#development) ## 项目状态 1.0 之前版本,正在积极开发中。 - 验证引擎、autopatch 和 CLI(`check`/`launch`/`rules`)均已 实现,并由自动化测试套件覆盖,这些测试直接针对测试机上安装的 真实二进制文件(`python`, `node`, `npx`)运行 -- 而非模拟(mocks)——包括通过真实生成 server 测试夹具进行的真正端到端 MCP 握手, 以及对 `launch` 的真实子进程级别测试。 - 尚未在 PyPI 上发布——请参阅[安装](#install)。 - 关于具体覆盖和不覆盖的内容,请参阅 [SECURITY.md](SECURITY.md)。 ## 范围 **在范围内:** 在到达 OS 进程生成层之前验证 stdio MCP server 的启动(command + args + env),专门用于封堵 [SECURITY.md](SECURITY.md) 中描述的命令/参数注入路径。 **明确不在范围内:** 扫描 server 的*声明的 tools* 以检查风险 能力(那是另一个问题——请参阅 AgentGuard),对生成的 进程进行沙盒隔离,以及非 stdio(SSE/HTTP)MCP 传输。 ## 安装 ``` git clone cd mcpshield pip install -e . # core CLI: click + rich only pip install -e ".[mcp]" # if you also want the Python autopatch (needs the `mcp` SDK) ``` **验证是否成功:** ``` mcpshield --version mcpshield --help ``` ## 快速入门 ### 选项 A:autopatch(Python MCP 主机) 如果你的应用是使用 Python 编写的,并且自行构建了 `StdioServerParameters` / 调用了 `mcp.client.stdio.stdio_client`,只需在你的入口点最顶部添加一个 import —— 在任何其他内容 import `mcp.client.stdio` 之前: ``` import mcpshield.autopatch # side-effect import; must come first from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client # ... 完全像以前一样使用 stdio_client —— 它现在已通过验证 ``` 不安全的启动现在会引发 `mcpshield.core.errors.UnsafeConfigurationError` (`ValueError` 的子类),而绝对不会生成进程。 ### 选项 B:静态检查(任意语言,零执行) 在未运行任何内容的情况下审核 `mcpServers` 样式的配置文件: ``` mcpshield check claude_desktop_config.json ``` ``` +---------------------------------------------------------------+ | Server | Status | Command | Detail | |------------------+---------+---------+------------------------| | filesystem | OK | npx | - | | evil-server | BLOCKED | npx | Argument '...' contains| | | | | shell metacharacter | +---------------------------------------------------------------+ 1 ok, 0 warned, 1 blocked ``` 如果存在任何 `BLOCKED` 的项目,将以非零状态退出(添加 `--strict` 以在出现 `WARN` 时也失败)—— 可以直接将其放入 CI 中。 ### 选项 C:启动监督器(非 Python 主机) 对于无法使用 Python autopatch 的 MCP 客户端(Node, Java, Rust, ...),将其配置指向 `mcpshield` 而不是真实命令: ``` { "command": "mcpshield", "args": ["launch", "--", "npx", "-y", "some-mcp-server"] } ``` `launch` 会先进行验证,然后使用你的 MCP 客户端期望的相同 stdio 执行真实命令(透明传递)—— 如果启动不安全,则会以明确的错误拒绝。 ## 拦截与警告的对比 | 检查项 | 原生二进制文件(例如 `python.exe`) | 可被 Shell 解释的(`.cmd`/`.bat`/shebang 脚本) | |---|---|---| | 参数中的 Shell 元字符(`&`, `\|`, `;`, backtick, `$(...)`, ...) | 允许 | **拦截** | | 参数中的 NUL 字节 / 换行符 | **拦截** | **拦截** | | 命令通过相对路径遍历(`..`)解析 | **拦截** | **拦截** | | 命令无法解析为真实文件 | **拦截** | **拦截** | | env 中的 `LD_PRELOAD` / `NODE_OPTIONS` / 等 | 剥离(警告) | 剥离(警告) | | env 中的 `PYTHONPATH` | 标记(警告),不剥离 | 标记(警告),不剥离 | 原生二进制文件获得了较宽松的参数检查,因为它们直接 `exec` —— 不存在会重新解析参数列表的 shell。可被 shell 解释的命令(最常见的是 Windows 上的 `npx.cmd`/`npx.bat`)会接受严格检查,因为这正是底层 CVE 利用所使用的确切机制。 ## 逃生舱 两者都是经过深思熟虑的、基于值的显式开启 —— 绝没有一刀切的“禁用检查”标志: - `allow_raw_args=["--some-value-with-a-pipe"]`(库)豁免你已经审查并信任的特定参数*值*。 - `allow_env=["SOME_VAR"]` 允许通常被剥离的环境变量不加修改地通过。 ## CLI 参考 | 命令 | 作用 | |---|---| | `mcpshield check [--format table\|json] [--strict]` | 对 `mcpServers` 配置进行静态审核。从不执行任何内容。如果存在任何 `BLOCKED`(或者使用 `--strict` 时连同 `WARN` 一起),则以非零状态退出。 | | `mcpshield launch -- [args...]` | 验证后,通过传递 stdio 执行真实命令。 | | `mcpshield rules list` | 显示处于活动状态的 shell 元字符黑名单、环境变量列表以及已知的安全启动器二进制文件。 | ## 已知限制 - 尚未在 PyPI 上发布 —— 安装需要 `git clone`。 - autopatch 只会修补在打补丁时查找到的 `mcp.client.stdio.stdio_client`。在执行 `import mcpshield.autopatch` 之前已经持有自身引用的代码(通过 `from mcp.client.stdio import stdio_client`)将会绕过它 —— 务必先 import mcpshield.autopatch。 - shell 元字符检查是基于黑名单的,仅在解析出的命令被检测为可由 shell 解释时才应用。它不是一个完整的 shell 语法解析器 —— 关于确切的范围边界,请参阅 [SECURITY.md](SECURITY.md)。 - `check` 使用运行它的机器来解析命令。在实际部署的机器上解析方式不同的配置(不同的 PATH,不同的已安装工具)在那里可能会产生不同的报告。 ## 项目布局 ``` mcpshield/ autopatch.py # one-line-import fix for Python MCP hosts core/ validate.py # the validation engine (command/args/env checks) rules.py # blocklist/allowlist data errors.py # UnsafeConfigurationError cli/ main.py commands/ (check.py, launch.py, rules.py) tests/ fixtures/ # real benign MCP server + sample/malicious configs ``` ## 开发 ``` pip install -e ".[dev,mcp]" pytest ``` 测试套件针对运行它的机器上安装的真实 `python`/`node`/`npx` 二进制文件进行验证(解析方式与引擎本身的解析方式相同),并包括通过真实生成的 server 测试夹具进行的真正端到端 MCP 握手 —— 而不是模拟。
标签:MCP, Python, 命令注入防御, 搜索语句(dork), 无后门, 漏洞防护, 进程隔离, 逆向工具