用途
Security Guidance Hook 是一个用于 Claude Code 的 PreToolUse 钩子(hook),而非斜杠命令。它的目标是在 Claude Code 把代码写入文件之前,拦截 12 类常见的安全反模式。安装后,它会在每次 Edit、Write 或 MultiEdit 操作前自动运行;一旦检测到已知的危险模式,就会发出警告并阻止该工具调用。
主要能力
钩子会同时扫描两处内容:
- 正在被编辑的文件路径——对带有风险 ${{ }} 模式的 GitHub Actions 工作流文件进行标记。
- 正在被写入的内容——对 11 项反模式做子串匹配。
被检测的模式包括:
- GitHub Actions 工作流表达式(基于路径)——来自不可信输入的工作流命令注入
- child_process.exec、exec(、execSync( ——Node.js 命令注入
- new Function ——JS 代码注入
- eval( ——JS 代码注入
- dangerouslySetInnerHTML ——React XSS
- document.write ——DOM XSS
- .innerHTML = ——DOM XSS
- pickle ——Python 反序列化 RCE
- os.system、from os import system ——Python 命令注入
- shell=True(subprocess)——Python 命令注入
- f-string SQL 或 .format SQL ——SQL 注入
- yaml.load(、yaml.unsafe_load ——YAML 反序列化 RCE
使用方式
工作流程如下:
- Claude Code 即将运行 Edit、Write 或 MultiEdit。
- PreToolUse 钩子触发,以 stdin 上的 JSON 形式把工具输入传给 security_reminder_hook.py。
- 钩子提取 file_path 与 content,并与模式表比对。
- 如果匹配到某个模式,且本会话中尚未针对该「文件+规则」显示过警告:向 stderr 输出警告(Claude 可见),以退出码 2 阻止工具调用,并把警告键保存到 ~/.claude/security_warnings_state_<session>.json。
- 如果匹配到模式,但本会话中已显示过该警告:允许工具调用(退出码 0)—— Claude 已经看到过一次警告。
- 如果未匹配任何模式:允许工具调用(退出码 0)。
安装命令(在 Claude Code 中):
/plugin marketplace add alirezarezvani/claude-skills
/plugin install security-guidance@claude-code-skills
该插件以 Claude Code 插件形式发布,带有 hooks.json 接线。安装后无需进一步配置,钩子会自动运行。
配置
按会话禁用(通过环境变量):
ENABLE_SECURITY_REMINDER=0 claude
# Hook is bypassed for this session
请谨慎使用——钩子最有用的时刻,恰恰是你最想禁用它的时候(例如在交付压力下要发布你自己也知道有问题的东西时)。
逐文件覆盖模式:如果某个特定文件确实需要 eval() 或 pickle(例如沙箱化的 REPL、为模糊测试器故意保留的不安全解析器),请在文件中用注释说明:
# SAFETY: pickle is the required serialization format for this internal tool.
# This file does NOT accept untrusted input. See SECURITY.md for boundary analysis.
import pickle
钩子仍会在本会话首次编辑时发出警告。确认之后,同一会话内的后续编辑将被允许(会话状态缓存)。
限制与说明
为什么模式基于子串而非 AST:AST 检测会更精确(不会对包含 "eval(" 的字符串字面量产生误报),但子串检测速度更快(毫秒级,不解析文件)、跨语言(同一钩子适用于 JS/TS/Python/YAML 等),且偏保守(误报易于忽略,一次按键即可;漏报则很危险)。对 90% 以上场景,子串检测已足够。若需要更严格的检测,可在 CI 步骤中叠加专门的 SAST 工具(semgrep、CodeQL)。
状态文件:钩子把「已显示警告」状态缓存在 ~/.claude/security_warnings_state_<session_id>.json。这些文件在 30 天后自动清理(每次钩子调用有 10% 概率触发清理),按会话隔离(每个 Claude 会话各有自己的文件),内容为 <file_path>-<rule_name> 键的 JSON 列表。可随时安全删除 ~/.claude/security_warnings_state_*.json 文件,钩子会在下次运行时重新生成。
调试日志:钩子写入 ~/.claude/security-warnings-log.txt 以便调试误触发:
tail -f ~/.claude/security-warnings-log.txt
# Shows JSON decode errors, state-file save failures, etc.
(上游版本写入 /tmp/security-warnings-log.txt,此处已移至 ~/.claude/ 以便重启后仍能保留。)
反模式(不推荐的做法):默认禁用该钩子、未经安全审查就修改模式列表(新增模式谁都可以,删除模式则需安全审查,因为模式对应真实 CVE 类别)、把会话状态当作不可变的安全策略(缓存用于防止反复打扰,但按会话生效,不应把「我忽略过一次」当作长期策略,应改用逐文件文档模式)。
来源与归属:该插件移植自 David Dworken 在 alirezarezvani/aeo-box 中 MIT 许可的实现。原有 9 个模式(GitHub Actions、child_process.exec、new Function、eval、dangerouslySetInnerHTML、document.write、innerHTML、pickle、os.system)连同其确切警告文本被原样保留。修改包括:新增 3 个模式(subprocess shell=True、通过 f-string 或 .format 的 SQL 注入、yaml.unsafe_load);调试日志从 /tmp/security-warnings-log.txt 移至 ~/.claude/security-warnings-log.txt;重构为 claude-skills 插件,归属信息置于 .claude-plugin/authoring-notes.json。
版本 2.7.3,许可证 MIT。
相关技能:engineering-team/skills/red-team(对抗性渗透测试)、engineering-team/skills/threat-detection(威胁建模与检测设计)、engineering-team/skills/ai-security(AI 特定安全,如提示注入等)、engineering/ship-gate(生产前审计,8 类约 89 项检查)、engineering/skill-security-auditor(技能包安全扫描)。