2026 年 7 月 11 日发布的 Claude Code v2.1.207 中,有一项容易被列表淹没但实际影响面不小的安全修复——插件系统中的 Shell 注入漏洞。本文详细解析这个漏洞的成因、修复方案,以及插件开发者需要做的适配。
漏洞是什么
官方 Changelog 原文:
Plugin hooks/monitors/MCP headersHelper:
${user_config.*}in shell-form commands is now rejected (shell-injection fix). Hooks: use exec form (args array) or$CLAUDE_PLUGIN_OPTION_<KEY>; monitors and headersHelper: read the value inside the script (config file or the server's env block).
翻译成人话:Claude Code 的插件系统允许开发者定义 Hooks(钩子)、**Monitors(监控器)**和 MCP headersHelper(请求头辅助函数),这些配置项中可以引用用户配置变量,语法是 ${user_config.某个键}。
问题在于:如果这些配置以 Shell 形式的命令字符串(而不是参数数组)来定义,并且直接把 ${user_config.*} 插值到 Shell 命令字符串中,攻击者就有机会通过精心构造的用户配置值,注入额外的 Shell 命令——这是经典的 Shell 注入模式。
# 危险模式(修复前可能存在的写法)
# hook 定义中直接把用户配置插值进 shell 命令字符串
"command": "echo ${user_config.username}"
# 如果 user_config.username 的值被设置为:
# "; rm -rf ~ #"
# 拼接后实际执行的命令变成:
# echo ; rm -rf ~ #
# 后半段的 rm -rf 会被当作独立命令执行这类漏洞的典型触发路径是:一个恶意的或被攻破的插件配置源,通过控制某个 user_config 字段的值,在受害者不知情的情况下让 Hook/Monitor 执行任意 Shell 命令。
官方修复方案
v2.1.207 从根源上拒绝了这种插值模式——${user_config.*} 在 Shell 形式命令中
直接被禁止使用。插件开发者需要改用两种安全的替代方案:
方案一:Hooks 改用 exec 形式(参数数组)
// 危险:shell 形式字符串命令
{
"command": "echo ${user_config.username}"
}
// 安全:exec 形式,参数以数组传递,不经过 shell 解析
{
"command": ["echo", "$CLAUDE_PLUGIN_OPTION_USERNAME"]
}exec 形式(args array)不经过 Shell 解析,参数直接作为独立的进程参数传递,从根本上避免了 Shell 元字符(;、|、`、$() 等)被注入执行的可能。
方案二:使用环境变量 $CLAUDE_PLUGIN_OPTION_<KEY>
# Hook 脚本内部读取环境变量,而不是在命令字符串里插值
#!/bin/bash
echo "当前用户:$CLAUDE_PLUGIN_OPTION_USERNAME"环境变量传递同样避免了字符串插值到 Shell 命令行的风险,因为变量值不会被 Shell 重新解析为命令的一部分。
Monitors 和 headersHelper:在脚本内部读取配置
monitors and headersHelper: read the value inside the script (config file or the server's env block).
对于 Monitors 和 MCP 的 headersHelper,官方建议在脚本内部从配置文件或服务器的 env 配置块中读取值,而不是在外层命令行中做字符串插值。
关联修复:pluginConfigs 不再读取项目级设置
同一版本还有一项相关的收紧措施:
Plugin option values (pluginConfigs) are no longer read from project-level
.claude/settings.json; only user,--settings, and managed settings are honored.
插件配置值(pluginConfigs)现在只能来自用户级设置、命令行 --settings 参数,或是企业统一管理的设置,不再读取项目级的 .claude/settings.json。
这项改动和 Shell 注入修复是同一条防线的两个层面:Shell 注入修复堵住了「恶意配置值被当作命令执行」的漏洞点;pluginConfigs 限制读取来源,则堵住了「恶意仓库通过提交项目级配置文件,为克隆者悄悄注入恶意插件配置」的攻击面。
攻击链路(修复前):
恶意仓库提交 .claude/settings.json,包含精心构造的 pluginConfigs
→ 开发者克隆并打开该仓库
→ 插件 Hook 读取项目级 pluginConfigs 中的恶意值
→ 恶意值插值进 shell 命令 → 任意命令执行
修复后:
恶意仓库提交的项目级 settings.json 中的 pluginConfigs 会被忽略
且即使读取到,shell 插值的攻击路径本身也已被禁止
两层修复叠加,显著提高了这类供应链攻击的门槛。
插件开发者需要做什么
如果你开发或维护 Claude Code 插件,升级到 v2.1.207 后需要检查:
- 审查所有 Hook 定义:是否用了 Shell 字符串形式 +
${user_config.*}插值的写法 - 迁移到 exec 形式或环境变量:按上文方案一/二改写
- 检查 Monitors 和 headersHelper:确保配置值是在脚本内部读取,而不是命令行插值
- 确认 pluginConfigs 依赖来源:如果插件设计依赖项目级配置传值,需要改为引导用户在用户级设置中配置
总结
v2.1.207 的这两项安全修复——Shell 注入拒绝和 pluginConfigs 读取来源收紧——虽然在版本说明里只是不起眼的两行,但实际上堵住了一条完整的、从「恶意仓库配置」到「任意命令执行」的攻击链路。如果你在团队中大量使用自定义插件、Hooks 或 MCP 集成,建议尽快升级并按上述指引审查现有插件配置。
来源:Claude Code Changelog v2.1.207 — Anthropic,2026-07-11