写入安全哨兵
将以下提示词粘贴到你的 AI 对话框中:
请根据 https://skillhub.cn/install/skillhub.md,安装 @user_3c6cb52e/security-guidance。
技能介绍
它解决什么问题
在 IDE 里让模型改文件,最大的风险不是模型「想错了」,而是它把想错的内容直接写进了磁盘。eval(、child_process.exec(、pickle、shell=True、f-string 拼 SQL,这些写法一旦落盘,通常要等到 CI 甚至线上才被发现。这个技能把检查点往前挪一步:在工具调用发生之前拦一次。
它是一个 hook,不是 slash command。安装后不需要额外调用,每次 Edit、Write、MultiEdit 之前会自动触发。
工作原理
- Claude Code 准备执行 Edit、Write 或 MultiEdit
- PreToolUse hook 触发,把工具输入以 JSON 形式通过 stdin 传给
security_reminder_hook.py - 脚本取出
file_path和content,分别做两类检查 - 命中规则且本会话该文件+该规则还没提示过:向 stderr 打印警告(Claude 能看到),以退出码 2 阻断调用
- 命中但本会话已提示过:放行,避免同一个文件反复打断
- 未命中:直接放行
检查分两个维度:
- 路径维度:编辑的文件是 GitHub Actions workflow 且包含
${{ }}表达式时标记,对应不可信输入导致的 workflow 命令注入 - 内容维度:对 11 类反模式做子串匹配,覆盖 Node.js 命令注入、JS 代码注入、React/DOM XSS、Python 反序列化 RCE、Python 命令注入、SQL 注入、YAML 反序列化 RCE
关于子串匹配而不是 AST:这是刻意的取舍。AST 更精确,但解析文件慢、且要按语言分别处理。子串方案更快(毫秒级)、跨语言(JS/TS/Python/YAML 用同一套逻辑)、偏保守(误报敲一次键就能过,漏报才是真正危险的)。作者判断 90% 以上场景够用,需要更严的检测应该另外在 CI 里叠 semgrep 或 CodeQL。
使用边界
误报是设计的一部分。 字符串字面量里出现 eval( 也会被拦。一次性放行,靠会话级缓存避免重复打扰。
合理特例用注释声明,而不是关掉 hook。 沙箱 REPL、fuzzer 里故意不安全的解析器这类场景,在文件里写注释说明理由,本会话首次编辑仍会警告,之后放行。
不要把它当长期安全策略。 ~/.claude/security_warnings_state_*.json 只是会话级去重缓存,「我之前点过一次放行」不等于这条规则被豁免了。另外这些状态文件每次调用有 10% 概率清理,30 天后也会过期,随时可以手动删除,hook 下次运行会重建。
改规则要经过安全评审。 规则对应的是真实 CVE 类别,加规则容易,删规则需要说明理由。
调试时可以看 ~/.claude/security-warnings-log.txt(上游版本写 /tmp/security-warnings-log.txt,这里改到了 ~/.claude/ 以便重启后保留)。
项目移植自 David Dworken 的 MIT 实现(原在 alirezarezvani/aeo-box),原有 9 条规则及警告文案保持原样,新增 subprocess shell=True、f-string/.format SQL、yaml.unsafe_load 三条。
使用场景
- 改 CI 脚本时防止 GitHub Actions 把 `${{ }}` 当表达式执行
- 模型生成 Node 后端代码时拦截 `execSync(` 等命令注入写法
- 模型写 React 组件时阻止 `dangerouslySetInnerHTML` 引入 XSS
- 模型写 Python 工具时拦截 `pickle` 反序列化与 `shell=True` 调用
适合人员
- 用 Claude Code 改代码、担心模型写入 `eval(` 或 `os.system` 的后端工程师
- 负责 Agent 落地、需要在工具调用前加安全检查的平台工程师
- 维护 GitHub Actions 仓库、要防 workflow 表达式注入的 DevOps 工程师
- 给模型开放写权限、需要一道自动拦截机制的安全负责人