SKILL 29 / SAFETY · ROUNDUP

安全与治理类 Skills 榜单

这一类只有一个验货问题:发现问题时它阻断,还是只是告诉你一声

2026-09-30 · BigCat

别的类别装错了只是白花钱,安全类装错了会给你一种「已经防住了」的错觉。本榜十二条都真实可装/可读,但分成两拨:能硬挡住你的(退出码非零、系统调用被拦),和只会写份报告的。两拨都有用,混着当一回事用就会出事。

同系列 → Skill 12 接 MCP 的安全边界(工具返回值即注入面那一层在那期)

// WHY THIS MATTERS

AI 写代码之后多出两个新战场——模型边写边扫,以及你装进来的 skill / MCP server 本身就是攻击面。本期把这两个和老三样(密钥扫描 / 依赖审计 / 越权检查)放进一张表,用一条判据排序:fail-closed 优先——不确定时默认拒绝,而不是默认放过。先给表和命令,判据放后半程。

// 01

先给清单:十二条,按「能不能阻断」排

论断:上半张表(①–⑤)会拦住你,下半张表(⑥–⑫)只会告诉你。装之前先知道自己买的是哪一种。
条目 出处 替你干掉的那件事 什么时候别装 / 别用 ━━━ 能阻断(确定性,退出码/系统调用说话)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ① sandbox(Bash 沙箱) 官方机制 · /sandbox 文件与网络越权由操作系统拦 原生 Windows(要 WSL2) ② permissions.deny 官方机制 · settings.json 硬禁某些工具/路径,收紧不放宽 你要的是「问我一下」 ③ gitleaks GitHub · MIT 密钥进 commit 前就退出码 1 已有 push protection 且够用 ④ trufflehog GitHub · AGPL-3.0 只报「验证过还活着」的密钥 AGPL 许可你的法务不接受 ⑤ osv-scanner GitHub · Apache-2.0 依赖漏洞按 OSV 库对账 你只用一种语言且生态自带 ━━━ 只会告诉你(模型审查/报告,不阻断)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ⑥ security-guidance 官方插件 · Anthropic 模型边写边被另一个模型复审 这台机器没有 Python 3.10+ ⑦ claude-security 官方插件 · Anthropic 多 agent 深扫 + SARIF + 补丁 嫌一次扫描的 token 太贵 ⑧ /security-review 官方内置命令 当前分支跑一遍安全 pass 你要的是每次都自动跑 ⑨ claude-code-security-review GitHub · MIT PR 上自动评论安全发现 会审外部贡献者的 PR ⑩ semgrep mcp GitHub · LGPL-2.1 规则型 SAST 挂进 agent 你不需要模型来调它 ⑪ zizmor GitHub · MIT 审 GitHub Actions 的越权与注入 仓里没有 workflow ⑫ snyk/agent-scan GitHub · Apache-2.0 扫你装的 MCP server 与 skill 你一个第三方 skill 都不装 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 另有两条「别装」:guardrails-ai(还活着,但那是给你的 LLM 应用用的,不是给 Claude Code 用的) protectai/llm-guard(据其 GitHub 页,2026-07-09 已 archived,别再往新项目里引)

怎么装(命令抄自各自官方页面 / 仓库 README)

# ①② 不用装,改配置就有。沙箱先看面板缺什么
/sandbox
# 要把沙箱当安全门禁而不是省事工具,这两个键必须显式写
{ "sandbox": { "enabled": true, "failIfUnavailable": true,
                "allowUnsandboxedCommands": false,
                "network": { "strictAllowlist": true, "allowedDomains": ["*.github.com"] } } }

# ③④⑤⑪ 确定性扫描器,装法都是一行
brew install gitleaks trufflehog zizmor
go install github.com/google/osv-scanner/v2/cmd/osv-scanner@latest
gitleaks git --report-path gitleaks-report.json   # 有发现 → 退出码 1
trufflehog git file://. --results=verified --fail # 有发现 → 退出码 183
osv-scanner scan source -r .
zizmor .github/workflows/                          # 支持 SARIF 输出接 CI

# ⑥⑦ 官方插件;⑧ 内置命令,什么都不用装
/plugin marketplace add anthropics/claude-plugins-official
/plugin install security-guidance@claude-plugins-official
/plugin install claude-security@claude-plugins-official   # 需要 python3 ≥ 3.9
/claude-security         # 菜单三件事:扫全库 / 扫改动 / 出补丁
/security-review         # 当前分支跑一遍,不用装任何东西

# ⑩ semgrep 的 MCP 现在是主仓的子命令(旧仓 semgrep/mcp 已归档)
claude mcp add semgrep -- semgrep mcp

# ⑫ 扫你自己装的那些 MCP server 与 skill;默认逐个问你才连
uvx snyk-agent-scan@latest scan

逐条说人话

那两条为什么进了「别装」 · guardrails-ai/guardrails(Apache-2.0,据其 GitHub 页 2026-09 约 7.5k star)活得很好,OnFailAction.EXCEPTION 正是 fail-closed 的写法——但它管的是你自己那个 LLM 应用的输入输出,不是你的编码 agent,放进本榜会误导人。protectai/llm-guard(MIT)的 input/output scanner 分类做得漂亮,但据其 GitHub 页已于 2026-07-09 归档、明示不再维护——当思路读可以,往新项目里引不行。
// 02

为什么这十二条不能混着比:两个轴,四个格

论断:横轴是谁做判断(写死的规则 / 模型读上下文),纵轴是发现之后会怎样(硬阻断 / 只报告)。右上角那格是空的,而且短期内会一直空着。
│ 规则写死(确定性) │ 模型读上下文(有语义) ────────────────────┼─────────────────────────────────┼──────────────────────────────── 发现就阻断 │ ① sandbox(系统调用层) │ (空) │ ② permissions.deny │ —— 没有一条敢让模型的判断 │ ③ gitleaks 退出码 1 │ 直接否决你的提交 │ ④ trufflehog --fail → 183 │ ────────────────────┼─────────────────────────────────┼──────────────────────────────── 只报告,你自己决定 │ ⑤ osv-scanner │ ⑥ security-guidance(三层都不阻断) │ ⑩ semgrep mcp │ ⑦ claude-security(补丁等你 apply) │ ⑪ zizmor(SARIF 进门禁才有牙) │ ⑧ /security-review │ ⑫ snyk/agent-scan │ ⑨ PR Action(评论,不挡合并) ────────────────────┴─────────────────────────────────┴────────────────────────────────

右上角空着不是产品没做完,是设计取舍:模型审查有误报,一条误报硬挡提交,团队第二天就会把整个检查关掉——连报告都没了。所以正确读法是:左列负责「绝不许发生」,右列负责「你最好看一眼」,谁也别替谁。

三种常见的错配:

翻车现场:CI 里装了 ⑨,PR 上每次都有漂亮的安全评论,团队很满意。半年后密钥泄漏——那条评论从来不挡合并,而这半年没人加过 ③。没人读的报告等于没装;退出码没人能绕过。
// 03

三分钟验货:装之前答这六问

论断:这一类不看星数,看它在不确定或出故障的时候默认做什么。默认放过的东西,别当门禁用。
  1. 它有发现的时候,退出码是几? 答不出来的就不是门禁。③ 是 1、④ 加 --fail 是 183,能直接进 CI。⑥⑦⑧⑨ 答案都是「不阻断」——记下来,别自我安慰。
  2. 它自己跑不起来的时候会怎样? 这一问最见功底。沙箱默认行为是依赖缺失或平台不支持就打个警告、不沙箱地跑下去——即 fail-open。要它硬失败必须显式写 sandbox.failIfUnavailable: true(官方注明这是给「把沙箱当安全门禁」的部署用的)。
  3. 有没有绕过它的合法通道? 有,官方写明了:沙箱违规时 Claude 可能带 dangerouslyDisableSandbox 重试,allowUnsandboxedCommands: false 关掉这条通道。⑫ 对应的键叫 --dangerously-run-mcp-servers。凡是名字里带 dangerously 的,先弄清它默认是开还是关。
  4. 这条配置放在哪一层才算数? 容易踩的一坑:sandbox.network.strictAllowlist(把「问一下」变成「直接拒」)只有写在用户设置、托管设置或 --settings 里才生效,写进仓库的 .claude/settings.json 完全没用。安全配置放错层等于没放。
  5. 它的误报谁来治? 有机制的才敢开门禁:③ 的 baseline + .gitleaksignore、④ 的 --results=verified、⑨ 那份排除清单。没有治理机制的高误报工具,装上就是等着被关掉。
  6. 它自己是不是攻击面? 这一问专门对付本类工具:⑨ 自己写了「未针对 prompt injection 加固,只审可信 PR」;⑫ 自己写了「扫配置可能执行命令」;⑤ 的 fix 可能执行包管理器脚本。安全工具读的就是不可信输入,这三条警告是它们诚实,不是它们差。
这一节的死线:⑫ 3.1k star、③ 29.6k star——这两个数不构成选型依据。依据是第 1、2 问:有发现时拦不拦,出故障时默认放不放。都答「放过」,那它是提醒工具,别写进合规文档。
// 04

诚实的代价:安全类是最容易「装了等于没装」的一类

论断:这一类的代价不是钱,是三种可预测的失效——告警疲劳、虚假安心、工具本身成为入口。

三笔账

不装任何东西,你还能怎么办

  1. 先敲 /security-review。 零安装零配置,先知道这个分支大概什么水位。
  2. 再开托管方自带的推送保护。 比装任何扫描器都省事,而且它真阻断。
  3. 然后才是 ③ 进 pre-commit。 一行 - id: gitleaks,性价比最高的一条 fail-closed。
那一格永远空着:① 能拦系统调用、③ 能拦提交、⑦ 能写 SARIF 和补丁——没有一样能判断「这个风险你的业务能不能接受」。⑦ 把这件事写进了产品设计:补丁永不自动应用。按不按那个 git apply,至今是人的活。

// 一页选购卡

先装这三个:① gitleaks 进 pre-commit(brew install gitleaks,一行 - id: gitleaks,有发现退出码 1)——唯一「今天装、今天就有牙」的。② /security-review——零安装,先摸清分支水位。③ /plugin install security-guidance@claude-plugins-official——边写边复审,但记住它不阻断。

按需再加:claude-security@claude-plugins-official(要 SARIF 报告与可 git apply 的补丁,接受 token 开销)· trufflehog --results=verified --fail(③ 误报多到没人看,且法务能接 AGPL)· osv-scanner scan source -r .(依赖多、语言杂)· zizmor .github/workflows/(仓里有 workflow,这格最常空着)· anthropics/claude-code-security-review(要 PR 级评论,且只审可信 PR)· uvx snyk-agent-scan@latest scan(装了第三方 skill / MCP server)· claude mcp add semgrep -- semgrep mcp(要 agent 自己能调 SAST)。

明确别做:把「有报告」当成「有门禁」 · 在老仓库上不出 baseline 就开密钥扫描门禁 · 让模型的安全判断直接否决提交 · 只审代码不审 .github/workflows/ 和装进来的 skill · 开了沙箱却不写 failIfUnavailable 与 allowUnsandboxedCommands · 把 strictAllowlist 写进仓库的 .claude/settings.json(不生效)· 往新项目里引 llm-guard(已归档)· 以为星数高就更安全。

// 术语表

fail-closed / fail-open
出故障或判断不了时,默认拒绝(closed)还是默认放过(open)。安全组件必须 fail-closed,而很多默认值是 open。
SARIF
静态分析结果的交换格式(2.1.0)。工具输出 SARIF,GitHub code scanning 就能直接读——报告要有牙通常靠它接门禁。
verified secret
trufflehog 的概念:捡到的凭据真去调一次服务方 API 确认还活着。代价是往外发请求,收益是误报大降。
baseline
先把现存命中存成一份报告,之后只看新增。老仓库开密钥扫描门禁的前提,否则必然告警疲劳。
tool poisoning
MCP server 或 skill 在自己的描述里藏恶意内容,靠被读进上下文操纵 agent。snyk/agent-scan 扫的正是这类。
sandbox.failIfUnavailable
Claude Code 设置项。沙箱起不来时默认只警告并照常运行;设为 true 才是硬失败。当门禁用就必须显式写。
strictAllowlist
沙箱网络设置项。非白名单域名从「问你一下」变成「直接拒」。只在用户、托管设置或 --settings 里生效。

// 延伸阅读