ElazarFuchs/mcp-intent-sentinel

GitHub: ElazarFuchs/mcp-intent-sentinel

MCP Intent Sentinel是一个静态分析工具,用于分类MCP服务器包的意图以增强安全性。

Stars: 0 | Forks: 0

# MCP Intent Sentinel ## 为何公布此数值 对MCP扫描器进行的最佳公开审计([appsecsanta, 2026年4月](https://appsecsanta.com/)) 得出结论:YARA式工具能捕获表面模式,但**无法区分标准的MCP指令与对抗性指令**,而人工审查仍然是最可靠的方法。该陈述针对的是当前已部署的扫描器。MIS提出的问题是:一个**语义级、意图级**的分析器(跨函数污点追踪 + 行为提取 + 别名跟踪 + 状态污染检测)能做到什么——更重要的是,*它*在哪里会失效? 答案就是上面那个数字。这里的贡献不在于分析器本身——而在于**围绕它的测量规范**: - **五层判定,而非三层。** 大多数工具将“我无法分析此内容”归为“此内容安全”——这是一种静默的误判绿色,当CISO首次在自己的服务器上运行该工具时,会迅速消耗信任。MIS在`benign`之上增加了`unknown`(未检测到工具,SDK模式未识别)和`shallow`(工具已识别但行为提取为空)。CI默认在两者出现时即失败。 - **报告中分离了良性列表。** `with extracted behavior`(真正的良性候选)被单独报告,区别于`zero behavior`(一个回归信号——此值应为0)。v0.1.4存在一个泄露,将4台服务器归为良性但无行为;v0.1.5将其作为内置自检暴露出来。 - **评估工具链公开列出下载失败的包名。** 51个注册表条目中有18个未能获取(已重命名、已退役、注册表错误)。明确报告它们可防止分母被静默筛选。 ## 测量基线(v0.1.5,51台服务器) | 项目 | 数量 | 占已扫描33台的百分比 | |---|---:|---:| | 下载成功 | 33 / 51 | — | | **下载失败**(已重命名/已退役/归档错误) | **18 / 51** | — | | 恶意 | 1 | 3.0% | | 可疑 | 2 | 6.1% | | **未知**(SDK模式未识别) | **18** | **54.5%** | | **浅层**(检测到工具,但行为不可提取) | **8** | **24.2%** | | **良性**(所有条目均提取到行为——零泄露) | **4** | **12.1%** | 这18个“下载失败”并非分析失败——它们是目前无法通过 `npm pack` / `pip download` 安装的包(通常是因为包在v0.1.3写入注册表和v0.1.5重新运行之间被重命名或退役)。它们连同错误字符串在 [`eval/results/v0.1.5/report.md`](eval/results/v0.1.5/report.md) 中按名称列出,以便任何人确认分母未被筛选。 这18个`unknown`和8个`shallow`条目是MIS自身覆盖范围的已命名缺口。大多数`unknown`是我们尚未教授分析器的TypeScript分派模式的长尾;大多数`shallow`是基于类的分派(LIMITATIONS中的L18)。 ## MIS的功能 一个CLI工具:`mis scan ` 输出一个判定 + 一个前三名的分类列表 + 适用于CI的JSON输出。五层判定: | 判定 | 含义 | CI默认行为 | |---|---|---| | `malicious` | 高置信度触发了意图规则 | 退出码 1 | | `suspicious` | 低/中置信度触发了意图规则 | 退出码 1 | | `unknown` | 未检测到工具注册(SDK模式不支持)— **非安全判定** | 退出码 1(使用`--allow-unknown`可选退出) | | `shallow` | 检测到工具,但任何工具均未提取到行为 — **非安全判定** | 退出码 1(使用`--allow-shallow`可选退出) | | `benign` | 检测到工具,至少从一个工具中提取到行为,未触发规则(受[L4](./LIMITATIONS.md)约束) | 退出码 0 | `--fail-on-verdict` 等级:`benign < shallow < unknown < suspicious < malicious`。 默认 = `shallow`。两个认知性判定(`shallow`、`unknown`)默认会使CI失败——需通过 `--allow-shallow` / `--allow-unknown` 显式选择退出。 ## 底层原理 仅静态分析——无沙箱,无执行。两个分析器为一个11条规则的意图分类器提供输入: - **Python分析器** (`mis/analyzers/python.py`) — AST + 每个工具的函数体分析。覆盖FastMCP (`@mcp.tool()`) 和官方低级SDK (`@server.list_tools()` + `@server.call_tool()` 及每个工具的分支归属)。通过每模块函数摘要进行跨函数污点追踪(L2部分闭包)。网络客户端别名跟踪 (`requests.Session()`, `httpx.Client()`, ...)。状态污染检测。 - **JS/TS分析器** (`mis/analyzers/js_ast.py`) — esprima AST + 感知绑定的工具检测。覆盖 `server.registerTool(name, config, handler)` 及标识符解析、`server.setRequestHandler(ListToolsRequestSchema, ...)`、旧版 `server.tool(...)`。具有与Python分析器相同的别名跟踪 + 跨函数污点追踪 + 状态污染检测。TypeScript源文件对每文件的差距回退到正则分析器。 - **清单分析器** — npm生命周期投递器 / setup.py投递器 / Damerau-Levenshtein相似域名检测。 意图分类器规则以一段简明英文输出判定及理由。单调递增:规则只能升级判定,不能降低。前三名分类列表按OWASP MCP Top 10进行标记。 ## 安装与使用 ``` pip install -e . # 本地源目录 mis scan ./path/to/mcp-server # 远程 mis scan github:anthropic/mcp-server-git mis scan npm:postmark-mcp@1.0.16 mis scan pypi:mcp-server-fetch # 适用于 CI 的机器可读格式 mis scan --json npm:foo ``` ## 复现测量 ``` pip install -e . python -m eval.run --out eval/results/my-rerun # 预计 ~5–10 分钟;需要在 PATH 中配置 npm 和 pip。 # 输出:eval/results/my-rerun/{report.md, run.json}。 ``` 完整复现指南、预期问题以及如何向注册表添加服务器,请参见 [eval/README.md](eval/README.md)。 ## v0.1.5 中未包含的内容 列表很长且已标注。要点: - **L1 — 无沙箱行为分析。** 仅静态分析。 - **L2 部分 — 过程间污点追踪仅覆盖模块级。** 类方法不可见(L18)。更深的辅助函数链(辅助函数的辅助函数)会丢失信号。 - **L8 — 无撕毁/突变检测。** 每次扫描都是快照。 - **L10 — 无针对已部署扫描器的测量。** mcp-scan(= snyk-agent-scan)是唯一的OSS MCP扫描器,但它检查的是MCP **配置 + 运行时工具描述**,而非源代码。不属于同类比较范畴。 - **L11 — 标注语料库是初始的,非广泛的。** v0.1.8发布框架及[eval/labeled/](eval/labeled/)中的5个种子标签;在更多恶意标签到来之前(L21记录了为何postmark-mcp@1.0.16返回`error`),精确率可计算,召回率无信息量。 - **L13 — 工具注册覆盖不完整。** 20台服务器(v0.1.7扫描集的60.6%)因SDK模式未被覆盖而被标记为`unknown`。 完整阅读[L1..L26]请参见[LIMITATIONS.md](./LIMITATIONS.md)。 ## 目录结构 ``` mis/ ├── analyzers/ │ ├── python.py # AST analyzer (FastMCP + official low-level SDK) │ ├── js_ast.py # esprima AST analyzer (closes L3) │ ├── js.py # regex fallback for TS source / parse failures │ ├── manifest.py # package.json / pyproject.toml / setup.py │ └── types.py # ToolProfile + BehaviorSignal enum ├── classifier/intent.py # 11 rules → verdict + reason ├── extractors/ # file:// / github: / npm: / pypi: ├── report/render.py # rich-table + JSON ├── cli.py # `mis` typer app ├── engine.py # scan() entry point └── findings.py # Finding + ScanResult + OWASP MCP constants eval/ ├── README.md # reproduction guide ├── registry.py # the 51 servers ├── run.py # harness └── results/{v0.1.3,v0.1.4,v0.1.5}/{report.md,run.json} tests/ # 84 unit + integration tests, 26 fixtures ``` ## 与相邻项目的关系 | 项目 | 层次 | 状态 | |---|---|---| | `mcp-trust` | Sigstore式信任 + 运行时代理 | v0.1-alpha | | `arsp` | 运行时安全平面:能力令牌、IFC、输出密封 | 研究阶段 | | `agent-config-injection` | 工作空间配置文件注入扫描器 (`.cursorrules`, `mcp.json`) | v0.1.8 | | **`mcp-intent-sentinel`** (此项目) | MCP服务器源代码的预安装意图分类 | v0.1.18 | 组合使用场景:`agent-config-injection`扫描工作空间中的配置文件,`mcp-intent-sentinel`在安装前扫描服务器源代码,`mcp-trust`在分发时验证签名制品,`arsp`在运行时强制执行能力策略。它们中没有任何一个能单独解决整个问题。 ## 如果MIS在某些地方失效 请提交一个issue。如果你发现评估工具误分类了一个服务器——一个真正的恶意服务器被判定为shallow/unknown/benign,或者一个真正的良性服务器被判定为malicious/suspicious——这将是最有价值的贡献。评估工具链的意义在于让我们能够基于数据进行讨论。 如果你从事MCP / agent安全工作,并希望就语义分析问题交流意见,我非常珍视这样的对话。 ## 许可证 [Apache 2.0](./LICENSE)。
标签:MCP协议安全, OWASP MCP Top 10, 云安全监控, 五种判决系统, 假阳性减少, 别名跟踪, 协议安全, 反取证, 安全扫描工具, 安全评估, 意图分析器, 意图分类, 意图检测, 数据可视化, 状态中毒检测, 网络安全, 行为提取, 覆盖差距分析, 逆向工具, 隐私保护, 静态分析