面向 MCP 工具描述、配置和源码字符串的静态安全扫描器,将 Agent 供应链威胁检测接入本地开发与 CI。
当前版本为 v1.6.1。运行时探针现可按 Server 声明的能力监控工具、资源、资源模板和提示词元数据,支持分页聚合与传统 MCP 协议版本选择,并继续对命令参数、对象标识及元数据内容进行脱敏。关键词规则会保留每一次实际命中的位置与证据。
- 基于 YAML 的 ATR 规则:正则和关键词匹配,启动时校验 schema、重复 ID 和正则表达式。
- 字段感知:JSON/YAML 显示
field_path;Python、TypeScript、JavaScript 扫描字符串字面量,减少函数名和结构文本误报。 - 上下文置信度:识别读取、执行、外发、隐藏指令等动作;安全校验代码中的敏感路径会降级为 LOW。
- Base64 二次匹配:支持标准、URL-safe、无 padding Base64;仅当解码内容命中恶意规则时确认混淆告警,并限制解码深度、大小和数量。
- 测试代码隔离:默认跳过
test/、tests/、__tests__/以及.test.*/.spec.*文件,可用--include-tests显式纳入并降级测试上下文告警。 - 结果聚合:按文件关联为攻击事件,告警去重,报告包含字段路径、行列位置、置信度和跳过文件清单。
- 完整性基线:覆盖普通文件和符号链接,支持忽略规则、目标绑定和可选 HMAC-SHA256 签名;哈希变化按高置信供应链事件报告。
- 输出与 CI:terminal、JSON、SARIF;
--fail-on控制流水线失败阈值。 - 运行时监控:通过 stdio 启动 MCP Server,按声明能力轮询
tools/list、resources/list、resources/templates/list和prompts/list,检测对象增删及安全相关元数据变化。 - 协议兼容:显式支持
2024-11-05、2025-03-26、2025-06-18和2025-11-25传统初始化握手;未知版本 fail-closed。 - 运行时保护:默认使用一次性工作目录和环境变量白名单,限制 stdout/stderr 总量与 JSON-RPC 消息数;策略摘要进入报告但不记录环境值和临时路径。
| 规则 ID | 威胁类别 | 默认严重级别 | 说明 |
|---|---|---|---|
ATR-DESC-INJECTION-001 |
prompt_injection | HIGH | Description 隐藏指令注入 |
ATR-DATA-EXFIL-001 |
data_exfiltration | CRITICAL | 参数或描述中的数据外带通道 |
ATR-CRED-THEFT-001 |
credential_access | CRITICAL | 敏感文件和凭证路径访问 |
ATR-RUG-PULL-001 |
supply_chain_poisoning | HIGH | list_tools 描述变化指示 |
ATR-ENCODE-OBFUS-001 |
obfuscation | MEDIUM | 解码后确认的编码载荷 |
git clone https://github.com/ookini-kawaii/mcp-security-scanner.git
cd mcp-security-scanner
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
# 也可以安装为命令行工具
pip install .
mcp-security-scanner --version# 默认 hunt profile:保留低置信线索,适合调查
python scanner.py test_cases/01_description_injection.json -r rules/
# enforce profile:只保留置信度 >= 70 的告警,适合 CI 门禁
python scanner.py . --profile enforce --format terminal --brief --no-report
# 包含测试文件(默认跳过测试目录和测试文件)
python scanner.py . --include-tests --profile hunt
# 输出 JSON 或 SARIF;目录扫描会生成一份聚合报告
python scanner.py test_cases/ --format json --no-report
python scanner.py test_cases/ --format sarif --no-report
# 仅在达到指定严重级别时让 CI 失败
python scanner.py . --profile enforce --fail-on high --format sarif
# 安装后建立 SHA-256 基线,之后校验文件是否被替换/增删
python scanner.py package/ --write-baseline package-baseline.json --no-report
python scanner.py package/ --baseline package-baseline.json --profile enforce --fail-on high
# 运行时检测 Rug Pull(运行时选项放在 Server 命令前)
python scanner.py package/ --runtime-polls 3 --profile enforce --fail-on high --runtime-command python mock_server.py
# 显式选择 Server 使用的传统 MCP 协议版本
python scanner.py package/ --runtime-protocol-version 2025-11-25 --runtime-command python mock_server.py
# 默认使用临时工作目录;依赖项目相对路径的 Server 应显式指定目录
python scanner.py package/ --runtime-cwd ./server --runtime-command python -m my_mcp_server
# 仅传递 Server 确实需要的环境变量;选项可重复
python scanner.py package/ --runtime-allow-env API_ENDPOINT --runtime-command python server.py
# 调整 stdout/stderr 总量和 JSON-RPC 消息数上限
python scanner.py package/ --runtime-max-output 2097152 --runtime-max-messages 512 --runtime-command python server.py
# 兼容旧 Server:继承全部环境变量(会扩大凭证泄露风险,不建议在 CI 使用)
python scanner.py package/ --runtime-inherit-env --runtime-command python server.py
# Server 若需要 -c 等自身参数,建议使用脚本文件或包装脚本;所有 runtime 选项放在 --runtime-command 前
# 可选:通过环境变量提供 HMAC 密钥,防止基线被静默修改
export MCP_SCANNER_BASELINE_KEY='replace-with-a-secret'
python scanner.py package/ --write-baseline package-baseline.json --require-signed-baseline --no-report
python scanner.py package/ --baseline package-baseline.json --require-signed-baseline --profile enforce
python scanner.py --versionhunt 展示所有线索,包括上下文不足、测试文件中的低置信结果;enforce 过滤置信度低于 70 的结果。--fail-on 可取 low、medium、high、critical 或 none,默认是 low。
| 退出码 | 含义 |
|---|---|
0 |
扫描成功,未达到 --fail-on 阈值 |
1 |
扫描成功,至少一个攻击事件达到阈值 |
2 |
目标、规则 schema、正则或报告写入失败,结果不可信 |
规则目录不存在、没有 YAML 规则、必需字段缺失、规则 ID 重复或正则无效时会 fail-closed,直接返回 2。
v2 基线默认覆盖目标目录中的全部普通文件和符号链接,并跳过 .git/。扫描器会读取目标根目录 .gitignore 的常用模式,可使用 --no-gitignore 关闭,或重复使用 --integrity-exclude PATTERN 添加排除项。这里支持常用通配符、目录和否定模式,不承诺覆盖 Git ignore 的所有边缘语义。
如果基线写在被保护目录内,CLI 会自动排除该基线文件。HMAC 密钥仅从 MCP_SCANNER_BASELINE_KEY 环境变量读取;签名用于验证共享密钥持有者生成的清单,不等同于公钥代码签名。
JSON 报告包含 findings、按目标聚合的 incidents、skipped_files、total_files、profile 和可选的 runtime 快照摘要。运行时命令参数、对象标识及完整元数据默认不写入报告,仅保留计数和可比对的 SHA-256 摘要;runtime.policy 只记录环境模式、工作目录模式、协议版本、已监控协议面和资源上限,不记录环境值或真实临时路径。每条 finding 包含:rule_id、severity、confidence、field_path、position(line:N,column:M)、runtime_surface、runtime_change、offset、decoded_from 等字段。SARIF 输出为 2.1.0,可直接导入 GitHub code scanning 等工具。
默认报告写入 reports/;该目录已加入 .gitignore。
mcp-security-scanner/
├── scanner.py # CLI 与兼容入口
├── mcp_security_scanner/ # v1.6.1 扫描引擎
│ ├── engine.py # 扫描编排、profile、去重
│ ├── extractors.py # 字段和源码字符串提取
│ ├── matching.py # 上下文匹配与置信度校准
│ ├── decoders.py # Base64 解码与边界控制
│ ├── correlation.py # 文件级攻击事件聚合
│ ├── integrity.py # SHA-256 基线与完整性校验
│ ├── runtime.py # MCP stdio 探针与运行时保护层
│ ├── reports.py # JSON/SARIF 序列化
│ └── rules.py # fail-closed 规则加载
├── rules/ # 5 条 ATR 示例规则
├── test_cases/ # 恶意召回样本
├── benchmarks/benign/ # 误报回归基准
├── .github/workflows/ # 测试矩阵与 SARIF 上传
├── pyproject.toml # Python 包与 CLI 安装元数据
└── tests/ # 自动化与精度回归测试
python -B -m unittest discover -s tests -v基准来源于《MCP 供应链安全检测实践》记录的 58 条误报:环境变量 .env、安全校验中的 /etc/passwd//etc/shadow,以及 PNG、函数名和 URL 被宽 Base64 正则误报。v1.2.0 通过字段感知、上下文窗口、测试目录策略和“解码后再确认”降低这些误报;v1.3.x 增加并强化了本地 Hash Pinning;v1.4.x 增加并加固 stdio tools/list 运行时差异检测;v1.5.0 增加环境、工作目录和输出资源保护;v1.6.0 将运行时差异检测扩展到资源、资源模板和提示词;v1.6.1 补齐关键词重复命中与证据精度。语义二次确认仍属于后续版本范围。
这是以静态规则为主、可选运行时探针为辅的扫描器,发现结果代表需要复核的风险信号,不等同于已确认漏洞。运行时探针当前支持 stdio JSON-RPC MCP Server,不覆盖 HTTP/SSE、鉴权、工具实际执行行为或网络流量分析。
运行时保护层不是操作系统级沙箱:临时工作目录不会阻止绝对路径文件访问,环境变量白名单不会阻止 Server 主动读取本地文件,当前也不会阻断网络连接。2026-07-28 使用逐请求协议元数据的新握手模型,v1.6.1 不宣称兼容;HTTP/SSE/Streamable HTTP 也不在本版本范围。对完全不可信的 Server,仍应在容器、虚拟机或独立低权限账户中运行扫描。
- ATR - Agent Threat Rules
- 《MCP 供应链安全检测实践》(本次 v1.2.0 精度基准与后续路线的来源)
本项目以 MIT License 发布。