返回更新列表
新发布Aug 21, 2026

mcp-stdio-shellguard v0.1.2

MCP stdio 服务器的纵深防御包:即插即用的 guardExec/guardSpawn 包装器、AST 审计 CLI、参考 MCP 服务器。修复了 Ox-Security 20 万服务器 stdio-RCE 类漏洞(LiteLLM CVE-2025-69256)。MIT 许可,TypeScript,Node >= 20。

分享

** StudioMeyer MCP Stack 的一部分** — 在马略卡岛构建 🌴 · 如果使用请⭐

mcp-stdio-shellguard

npm version npm downloads License Last commit GitHub stars

针对 MCP stdio 服务器的深度防御捆绑包。使用白名单 + 沙箱 + 重放检测包装 child_process.exec/spawn,外加一个 AST 审计 CLI (mcp-shellguard-audit),用于扫描 MCP 服务器源中未清理的 shell 调用。封堵了 Ox-Security MCP stdio-RCE 漏洞类别(200k 台易受攻击服务器,2026 年 5 月披露)。

  • MCP spec: 2025-06-18
  • SDK: @modelcontextprotocol/sdk ^1.29.0
  • Node: >= 20
  • License: MIT
  • Author: Matthias Meyer (StudioMeyer)

安装

npm install mcp-stdio-shellguard

或者直接运行审计 CLI 而无需安装:

npx -y -p mcp-stdio-shellguard mcp-shellguard-audit scan ./src

它为您提供了什么

三个层次,可逐层选择使用:

  1. 库 API — 可直接使用的 guardExec / guardSpawn,您可以从自己的 MCP 服务器中调用。默认拒绝白名单、沙箱配置文件、重放窗口。
  2. 审计 CLImcp-shellguard-audit scan <path> 遍历 AST,报告 12 种反模式,从 LOW(no timeout)到 CRITICAL(exec(\...${userInput}...`)`)。
  3. 参考 MCP 服务器mcp-stdio-shellguard-demo 公开了 8 个工具,以便 MCP Inspector / Claude Desktop 可以直接驱动这个捆绑包。

工具(参考服务器)

工具类型用途
guard_execdestructive受保护的 child_process.exec。强制使用 args[] 向量、白名单 + 沙箱 + 重放。返回 stdoutstderrexitCodecanonicalHashisReplaytrustTier
guard_spawndestructive受保护的 child_process.spawn。返回 stdout/stderr 的 SHA-256 哈希值而非完整内容。硬性拒绝 shell:true
register_allowlistmutating使用可执行文件 + 参数正则表达式注册工具名称。未注册时应用默认拒绝。
audit_sourceread-only扫描 TS/JS 路径以查找 shell 注入反模式。返回 AuditFinding[] + 摘要。
audit_reportread-only将审计结果格式化为 markdown / json / SARIF 2.1.0。
replay_checkread-only计算调用的规范 SHA-256 哈希值,并报告它是否已在重放窗口中。
sandbox_statusread-only报告活动的沙箱配置文件 + 具体限制 + cgroup-v2 活动标志。
trust_tierread-only为已注册的工具推导出 LOW/MEDIUM/HIGH/CRITICAL 等级,以及改进提示。

沙箱配置文件

配置文件超时时间最大 stdout最大 stderr文件描述符预算cgroup-v2
strict5 s1 MB256 KB32yes (cpu/memory)
standard (default)30 s10 MB1 MB256yes
permissive5 min100 MB10 MB1024no

调用者可以通过每次调用的 timeoutMs / fdBudget 来收紧。调用者不能放宽超出配置文件的限制。

信任等级

等级条件
LOW工具未注册(默认拒绝)
MEDIUM已注册但 argsPatterns 为空(允许任何参数)
HIGH设置了 argsPatterns 但沙箱或重放跟踪器未激活
CRITICALargsPatterns + 沙箱 + 重放全部激活

通过注册工具 + 设置 argsPatterns + 通过 guardExec/guardSpawn 运行(始终激活沙箱 + 重放)来将 LOW 提升为 CRITICAL。

库快速入门

import {
  AllowlistRegistry,
  ReplayWindow,
  guardExec,
} from "mcp-stdio-shellguard";

const registry = new AllowlistRegistry();
const replay = new ReplayWindow();

registry.register({
  toolName: "git-log",
  executable: "/usr/bin/git",
  argsPatterns: ["^log$", "^--oneline$", "^-n$", "^\\d+$"],
  sandboxProfile: "strict",
});

const result = await guardExec(
  {
    toolName: "git-log",
    command: "/usr/bin/git",
    args: ["log", "--oneline", "-n", "10"],
  },
  { registry, replay },
);

console.log(result.stdout); // → commit lines
console.log(result.trustTier); // → "CRITICAL"
console.log(result.canonicalHash); // → 64-char SHA-256

审计 CLI

mcp-shellguard-audit scan ./src
mcp-shellguard-audit scan ./src --format sarif --output audit.sarif
mcp-shellguard-audit scan ./src --severity-floor HIGH    # CI gate

退出代码:

  • 0 干净(找不到达到或高于下限的问题)
  • 1 存在问题
  • 2 解析 / IO 错误

反模式库(12 条规则)

ID严重性触发条件
exec_template_literal_with_inputCRITICALchild_process.exec(\ls ${x}`)`
exec_dynamic_stringCRITICALchild_process.exec(cmd)
exec_sync_dynamic_stringCRITICALchild_process.execSync(cmd)
eval_near_child_processCRITICALeval(...)
function_constructor_near_child_processCRITICALnew Function(...)
spawn_dynamic_file_argsHIGHspawn(bin, userArgs)
exec_file_dynamicHIGHexecFile(bin, ...)
shell_true_optionHIGH{ shell: true }
os_system_equivalentHIGHDeno.run / Bun.spawn
spawn_literal_dynamic_argsMEDIUMspawn('git', userArgs)
unbounded_bufferLOWexec without maxBuffer
missing_timeoutLOWexec/spawn without timeout

扫描器在匹配前解析了重命名child_process 绑定,因此即使调用通过别名而非字面量的 child_process.exec,以下危险形式也会被捕获:

  • const execAsync = promisify(exec); execAsync(...${x})
  • import cp from "node:child_process"; cp.exec(...${x})
  • const { exec: sh } = require("child_process"); sh(...${x})
  • import { exec as run } from "node:child_process"; run(...)

同步变体(spawnSyncexecFileSync)共享其异步规则,并且 shell_true_option 也会在字符串 shell({ shell: "/bin/sh" })或动态 shell 值上触发——而不仅仅是字面量 { shell: true }。对非 child_process 函数的 promisify、从其他模块解构、以及 { shell: false } 保持干净(无误报)。

编译指示

  • // shellguard:ignore-next-line — 抑制一条结果
  • // shellguard:ignore-file — 抑制整个文件(很少使用;建议逐行抑制)

为什么存在

Ox-Security 披露(2026 年 5 月)超过 20 万个 MCP stdio 服务器将 child_process.exec 与包含直接来自 LLM 工具参数的用户输入的模板字面量包装在一起。LiteLLM v1.83.6 是典型示例(CVE 在 1.83.7 中修补)。此捆绑包是防御安全对应物:一个可直接使用的防护 + 扫描器,封堵了该漏洞类别。灵感来自 AWS Linux seccomp + Chromium 沙箱等级。

另请参阅

许可证

MIT — Copyright (c) 2026 Matthias Meyer (StudioMeyer)

分类