kabbersokhi-boop/native-mcp-sandbox

GitHub: kabbersokhi-boop/native-mcp-sandbox

一个基于 C++20 的安全优先型 MCP 原生沙盒服务器,通过严格的资源限制和信任边界让 AI agent 在无 shell 或任意文件访问权限的情况下安全检查宿主机证据。

Stars: 0 | Forks: 0

# 原生 MCP 沙盒 [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/kabbersokhi-boop/native-mcp-sandbox/actions/workflows/ci.yml) [![Tag](https://img.shields.io/github/v/tag/kabbersokhi-boop/native-mcp-sandbox?label=tag)](https://github.com/kabbersokhi-boop/native-mcp-sandbox/tags) [![License](https://img.shields.io/github/license/kabbersokhi-boop/native-mcp-sandbox)](LICENSE) [![C++20](https://img.shields.io/badge/C%2B%2B-20-blue.svg)](https://en.cppreference.com/w/cpp/20) [![Linux](https://img.shields.io/badge/platform-Linux-lightgrey.svg)](https://www.kernel.org/) 原生 MCP 沙盒探讨了一个实际问题: **AI agent 如何在不获得 shell、任意文件访问权限、原始进程内存或广泛的操作系统权限的情况下,检查有用的宿主机证据?** 本仓库给出的答案是一个具有严格限定信任边界的小型原生服务器。操作员可以选择可以被观察的文件和进程。然后,MCP 客户端可以通过标准输入和标准输出使用四个受限的、只读的工具。 最新的标记发布版本是 **v0.10.1**,对应的 commit 为 `2e19b5b6a14f5fbe26c5b4094c1750c6c5205db1`。阶段 0–9 已完成。不可变的 **v0.10.0** 发布版本作为历史上下文保留;v0.10.1 是修正版本。阶段 10 目前仅处于规划阶段(通过 PR #13)。 目前尚不存在任何阶段 10 的实现、提供者客户端、网络功能、凭证或新的 MCP 工具。 ## 本项目存在的原因 许多 agent 工具都以强大的原语(例如 shell、文件系统浏览器或通用的进程 API)作为起点。这种方法很方便,但也造成了巨大的安全边界。 原生 MCP 沙盒采取了相反的方法: - 公开一小组专用工具; - 要求显式的操作员策略; - 接受符号名称,而不是原始路径和 PID; - 强制执行固定的资源限制; - 当严格的内核保护不可用时,安全关闭; - 将畸形输入、竞态、取消和资源压力作为首要行为进行测试。 本项目在以下方面非常有用: - 作为安全 MCP 工具设计的参考; - 作为现代 C++ 系统工程的代表作; - 作为对 Linux 描述符和进程身份控制的研究; - 作为确定性 agent 证据收集的可复现演示; - 作为未来基准测试和互操作性的基础。 ## 服务器能做什么 可信的运行时策略可以启用四个工具。 | 工具 | 用途 | 重要边界 | | --- | --- | --- | | `logs.search` | 在一个已批准的日志文件中搜索字面文本 | 无递归搜索或任意路径 | | `logs.tail` | 读取最后几行日志的有界预览 | 无文件监视或无界输出 | | `elf.inspect` | 检查选定的 ELF32 和 ELF64 元数据 | 目标永远不会被执行或加载 | | `proc.memory` | 读取一个命名进程的汇总内存计数器 | 无原始内存、映射、命令行、环境或进程发现 | 如果没有策略,服务器不会暴露任何宿主机工具。 ## 它的不同之处 ### 客户端不能选择原始权限 MCP 客户端选择由操作员定义的名称,例如 `evidence` 或 `server`。它不能提交任意的绝对路径或原始 PID。 ### 文件保留在已批准的根目录内 严格的文件系统模式使用 Linux `openat2`,并带有针对目录遍历、符号链接、魔术链接和挂载点交叉的控制。接受的文件通过拥有的描述符保持锁定。 ### 进程身份被锁定 严格进程模式要求相同的 effective UID 和 pidfd。服务器还会保留进程目录,并在每次观察前后重新验证进程身份。 ### 工作负载是有界的 服务器使用固定的双线程调度器。它限制了未完成的调用、请求大小、响应大小、JSON 深度、token 数量、文件读取次数、搜索结果和工具截止时间。 ### 失败也是设计的一部分 测试套件涵盖了畸形 JSON、重复键、超大输入、策略拒绝、进程退出、取消操作、截止时间竞态、饱和状态、工作线程构建失败、并发关闭和输出帧问题。 ## 确定性调查演示 发布的 v0.10.1 修正版包含一个使用真实服务器的完整调查客户端。 该演示: 1. 通过其 MCP stdio 接口启动 `native-mcp-sandbox`; 2. 加载一个合成的事件日志; 3. 创建一个不可执行的 ELF 测试固件; 4. 验证确切的四工具接口; 5. 运行固定序列的日志、ELF 和进程观察; 6. 通过 JSON-RPC ID 关联响应,即使它们是乱序完成的; 7. 编写规范的 JSON 和 Markdown 报告; 8. 证明两次独立运行产生字节级相同的输出。 该场景遵循服务重启、身份验证失败、有限重试、恢复以及健康的最终状态的过程。 报告仅包含稳定的证据。它排除了运行时 PID、UID、内存总量、临时路径、地址和当前时间戳。 ## 快速开始 ### 前置要求 - Linux - CMake 3.20 或更高版本 - Ninja - 支持 C++20 的 GCC 或 Clang - Python 3 - nlohmann/json 3.11 或更高版本 - procfs - Linux `openat2` 支持 - 用于严格进程模式的 pidfd 支持 在 Ubuntu 上,安装常见的构建依赖项: ``` sudo apt-get update sudo apt-get install --yes build-essential cmake ninja-build nlohmann-json3-dev python3 ``` ### 构建和测试 ``` git clone https://github.com/kabbersokhi-boop/native-mcp-sandbox.git cd native-mcp-sandbox cmake --preset dev cmake --build --preset dev ctest --preset dev --output-on-failure ``` 检查可执行文件: ``` ./build/dev/native-mcp-sandbox --version ./build/dev/native-mcp-sandbox --self-check ``` ### 运行确定性演示 ``` mkdir -p ./build/agent-investigation-output python3 scripts/run_agent_investigation_demo.py \ --server ./build/dev/native-mcp-sandbox \ --fixture ./demo/investigation/application.log \ --output-dir ./build/agent-investigation-output ``` 该命令会创建: ``` build/agent-investigation-output/report.json build/agent-investigation-output/report.md ``` 已提交的 golden 报告位于 [`demo/investigation/`](demo/investigation/) 中。 ## 配置服务器 运行时策略将符号名称映射到操作员批准的资源。 示例版本 2 策略: ``` { "version": 2, "roots": [ { "name": "evidence", "path": "/srv/approved-evidence", "maxFileBytes": 16777216 } ], "processes": [ { "name": "server", "pid": "self" } ] } ``` 启动已配置的服务器: ``` ./build/dev/native-mcp-sandbox --policy-config ./policy.json ``` 服务器通过标准输入和标准输出使用换行符分隔的 JSON-RPC 2.0。它的目标是 MCP 修订版 `2025-11-25`。 请参阅 [`ARCHITECTURE.md`](ARCHITECTURE.md) 了解协议路径,并参阅 [`SECURITY.md`](SECURITY.md) 了解安全期望。 ## 示例 MCP 生命周期 未配置的服务器支持 MCP 生命周期,但不公布任何工具: ``` ./build/dev/native-mcp-sandbox <<'MCP_INPUT' {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"demo-client","version":"1.0"}}} {"jsonrpc":"2.0","method":"notifications/initialized"} {"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}} MCP_INPUT ``` 已配置的服务器仅公布由其策略启用的工具。 ## 架构一览 ``` MCP client | | newline-delimited JSON-RPC 2.0 v Protocol parser and lifecycle gate | +--> bounded JSON preflight +--> closed request schemas +--> cancellation and deadline context v Fixed two-worker scheduler | +--> filesystem policy --> logs.search / logs.tail / elf.inspect | +--> process policy ----> proc.memory v Serialized bounded JSON-RPC responses ``` 核心设计选择包括: - C++20,带有小型协程桥接和固定的工作线程池; - 没有每个请求一个线程的模型; - 基于描述符的文件系统隔离; - 相同 UID 和 pidfd 支持的进程观察; - 有界解析器和显式输出 schema; - 确定性和覆盖率引导的对抗性测试; - 原生 Linux 执行,无需容器。 设计决策记录在 [`docs/adr/`](docs/adr/) 中。 ## 工程与保障 本项目跨越多个编译器和分析模式进行了测试。 | 领域 | 覆盖范围 | | --- | --- | | 编译器 | GCC Debug 和 Clang Release | | 内存安全 | AddressSanitizer、UndefinedBehaviorSanitizer 和泄漏检测 | | 并发 | 专注的 ThreadSanitizer 调度器测试 | | 变异测试 | 普通 CTest 构建中的确定性变异运行器 | | 覆盖率引导的模糊测试 | 五个可选的 Clang libFuzzer 目标 | | 集成 | 真实的 stdio 服务器执行、严格的 `openat2`、pidfd、AF_UNIX 和 FIFO 检查 | | 确定性 | 双运行字节相等性和已提交的 golden 报告 | | 负面行为 | 输出泛洪、过时报告、畸形协议输入、被禁止的报告字段以及资源限制 | ### 已记录的发布证据 对于 **v0.10.0**: - 合并后的全部五个 GitHub Actions 作业均已通过; - 该演示在 GCC、Clang 和 sanitizer CTest 套件中均通过; - 严格演示未使用任何遗留兼容性标志; - 确定性的 JSON 和 Markdown 报告与已提交的 golden 文件相匹配; - 输出泛洪和被禁止字段的负面测试通过。 - 阶段 9 添加了有限的可复现性基准测试,包含离线报告验证 和仅测量的对照组。 不可变的 v0.10.0 标签包含历史遗留的陈旧编译版本 标识符 0.9.0。修正发布 v0.10.1 被标记在 `2e19b5b6a14f5fbe26c5b4094c1750c6c5205db1`。 对于阶段 7 的保障活动: - 两次确定性活动各完成了 100,000 次迭代; - 重复的 ThreadSanitizer 调度器测试通过; - 严格的 `openat2`、pidfd、AF_UNIX 和 FIFO 集成通过; - 五次 600 秒的 libFuzzer 活动总共执行了 **61,925,751 个输入**; - 这些记录在案的活动没有产生任何观察到的崩溃、sanitizer 发现、超时或崩溃产物。 这些结果适用于经过测试的构建和输入。它们不能证明完全的正确性、内存安全性或安全性。 详细的证据记录在 [`PHASE_8_MANIFEST.md`](PHASE_8_MANIFEST.md)、[`PHASE_7_MANIFEST.md`](PHASE_7_MANIFEST.md) 和 [`docs/FUZZING.md`](docs/FUZZING.md) 中。 ## 安全边界 本仓库有意 **不** 提供: - shell; - 任意文件读取; - 递归文件系统搜索; - 文件系统修改; - 网络功能; - 原始进程内存; - 进程映射、命令行、环境或文件描述符; - 进程发现; - 进程控制; - 反汇编或恶意软件分类; - 硬实时取消; - MCP 任务或持久化作业队列。 针对较旧的内核存在兼容模式,但它们是显式选入的,并具有文档记录的限制。严格模式是默认的安全目标。 在扩展宿主机权限之前,请阅读 [`THREAT_MODEL.md`](THREAT_MODEL.md)。 ## 仓库指南 ``` include/native_mcp/ Public C++ interfaces src/ Server and policy implementation tests/ Unit, integration, stress, and security tests fuzz/ Corpora, dictionaries, and fuzz targets scripts/run_agent_investigation_demo.py Deterministic Phase 8 client demo/investigation/ Synthetic fixture and golden reports docs/adr/ Architecture decision records ARCHITECTURE.md Detailed architecture SECURITY.md Security policy THREAT_MODEL.md Assets, controls, and residual risks docs/FUZZING.md Native fuzzing and triage guide ``` ## 项目路线图 - 阶段 0–9:已完成;`v0.10.0` 仍为不可变的历史发布状态 并且 `v0.10.1` 是当前的修正发布,位于 `2e19b5b6a14f5fbe26c5b4094c1750c6c5205db1`。 - 阶段 10:仅处于规划阶段(通过 PR #13)。尚未添加任何实现、提供者客户端、 网络功能、凭证或新的 MCP 工具。 每个阶段都作为一个有界的、可审查的增量进行开发。新的权限需要明确的威胁模型决策。 ## 文档风格 README 是为开发人员、审查人员和招聘人员编写的。 技术规范和流程使用符合 ASD-STE100 Issue 9 的风格。请参阅 [`docs/WRITING_STYLE.md`](docs/WRITING_STYLE.md)。 ## 贡献 只要能保持严格的安全边界并包含适当的测试,我们欢迎您的贡献。 请从 [`CONTRIBUTING.md`](CONTRIBUTING.md) 开始。对安全敏感的更改还必须遵循 [`SECURITY.md`](SECURITY.md),并在假设发生变化时更新 [`THREAT_MODEL.md`](THREAT_MODEL.md)。 ## 许可证 Apache License 2.0。请参阅 [`LICENSE`](LICENSE)。
标签:AI代理, Bash脚本, C++20, MCP, 安全基础设施, 智能代码审计, 沙箱, 逆向工具