Claude Code 的安全模型:三份安全文档各自管的是哪一层

2026-08-18

翻 Claude Code 文档时有个很容易踩的坑:搜「security」会同时命中三处内容——code.claude.com/docs/en/securitycode.claude.com/docs/en/security-guidancecode.claude.com/docs/en/claude-security。名字长得像,但它们管的根本不是同一件事。把它们当成一回事的人,通常会在某个时刻发现自己配了半天的东西完全没覆盖到真正想防的风险。

这篇就沿着一条具体路径走一遍:你让 Claude 改一个文件、跑一条命令、然后提交。这一路上分别有什么在起作用,各自由哪份文档定义。

先把两类完全不同的风险分开

第一类风险是:Claude Code 能对你这台机器做什么。它会读文件、写文件、跑 shell 命令、连 MCP 服务器。这一类由 security 那一页管,核心是权限、边界和信任验证。

第二类风险是:写出来的代码里有没有漏洞。这跟有没有权限毫无关系——它完全在授权范围内工作,照样可以给你写出一处注入。这一类由两个插件管:security-guidance 管「Claude 正在写的代码」,claude-security 管「仓库里本来就有的代码」。

混起来就会出现「我开了 sandbox,代码安全应该没问题了吧」这种想当然的推论。文档里这两块是分开写的,配置项完全不重叠。

第一层:动作发生之前,权限系统在拦什么

security 页写明,Claude Code 默认使用严格的只读权限(strict read-only permissions by default),需要编辑文件、跑测试、执行命令时才请求明确授权。文档同时说明,有一组内置的只读命令(该页举的例子是 lscatgit status)不会触发提示。

几个具体边界值得记住:

工作目录边界。 文档写明 Claude Code 只能写入它启动时所在的目录及其子目录,未经明确授权不能修改上级目录的文件。用 Read、Grep、Glob 读边界之外的路径是可以的,但会先弹一次批准提示。想跳过这个提示,用 additional directories 扩展边界;想反过来收紧只读 Bash 命令能触及的范围,用 sandbox 的 denyRead 规则——注意文档特别标了这条只在启用 sandboxing 时生效sandbox 的边界用 /sandbox 配置。

Accept Edits 模式的确切范围。 这个模式常被理解成「全放开」,但文档写得很具体:它自动批准文件编辑,以及工作目录内路径上的一组固定文件系统 Bash 命令——mkdirtouchrmmvcpsed。其它 Bash 命令和范围外的路径仍然会提示。rm 在这个列表里,这一点值得你在开这个模式前先看清楚。

联网类命令。 文档写明,从网上取内容的命令(如 curlwget)默认不会被自动批准,它们和其它非只读 Bash 命令一样弹提示,你可以单次批准,也可以加一条明确的允许规则:

Bash(curl *)

想彻底禁掉,文档给的做法是把它们加进 permissions.deny

几条兜底规则。 未匹配的命令默认要求手动批准(文档称为 fail-closed matching);可疑的 bash 命令即使之前已在允许列表里也会重新要求手动批准;web fetch 使用独立的上下文窗口,避免把可能带恶意指令的内容注入主上下文。

信任验证的两个坑。 文档写明首次在某个代码库运行、以及新增 MCP 服务器时需要信任验证,但紧跟着有两条注记:用 -p 非交互运行时信任验证是关闭的;直接在家目录启动 Claude Code 时,信任接受只在当前会话内有效、不写盘,所以每次启动都重新提示,而且没有设置项能让它持久化——文档给的建议是改从项目子目录启动。

Windows 侧必须单看的两条

凭据存储三个平台不一样:文档写明 API key 与 token 在 macOS 上可用时存入 Keychain,在 Windows 和 Linux 上则依靠文件权限保护。这是机制差异,但它意味着你在 Windows 上对本机文件权限的假设直接决定了这一层的强度。

另一条是 Windows 专属警告,security 页用 Warning 框标出:在 Windows 上运行 Claude Code 时,官方不建议启用 WebDAV,也不建议让它访问 \\* 这类可能包含 WebDAV 子目录的路径。文档给的理由是 WebDAV 已被微软标记为 deprecated,启用它可能让 Claude Code 触发到远程主机的网络请求、绕过权限系统。这句分量不轻,Windows 用户建议去看原文。

security 页末尾还有一个 Warning:这些保护措施显著降低风险,但没有任何系统能完全免疫所有攻击。所以别指望配完这些就万事大吉。

第二层:编辑落盘之后,security-guidance 在三个点上查

security-guidance 是个插件,装了之后自动运行,文档明说没有命令要记。它审的是Claude 自己写的代码,检查点有三个,深度递增:

  1. 每次文件编辑后:对新内容做已知风险模式匹配。文档写明这是纯字符串匹配、不调模型、不产生用量成本。举的类别包括动态代码执行(eval(new Functionos.systemchild_process.exec)、不安全反序列化(pickle)、DOM 注入(dangerouslySetInnerHTML.innerHTML =document.write),以及对 .github/workflows/ 下文件的编辑。同一个 pattern 在同一文件同一会话里只告警一次。
  2. 每轮对话结束时:对这一轮工作树里的全部变更算一个 git diff,交给另一次独立的、聚焦安全的 Claude 审查,后台跑,不拖慢回复。文档列的目标是字符串匹配抓不到的那类:越权、不安全的直接对象引用、注入、SSRF、弱加密。
  3. Claude 每次 commit 或 push 时:跑更深的 agentic 审查,会读周边代码(调用方、sanitizer、相关文件)再判断一处发现是不是真的。

这一层最容易误解的一点:第三个检查点只对 Claude 通过它的 Bash 工具执行的 commit / push 触发。你自己在终端里敲的提交,包括会话内用 ! shell escape 跑的提交,都不会被审查。另外,每轮审查覆盖的改动文件数、连续重新触发的次数、每小时提交审查次数都设了上限,超过就不再触发——具体数值以官方文档为准。

还有一句必须照实转述:这三层都不阻断写入,也不阻断提交(None of the layers block writes or commits)。发现的问题是以指令形式送回给正在写代码的那个 Claude,由它在对话里处理,而审查模型本身也可能漏。文档自己把它定位成纵深防御里的一层,不是完整的安全方案。要硬阻断,文档给的路子是配一个会阻止编辑的 hook,或者放到 CI 里卡。

两个扩展点

模型驱动的那两层可以喂自定义指南,写在 .claude/claude-security-guidance.md 里,用大白话描述你的威胁模型和审查清单。文档给的示例长这样:

# Security guidance for this repo

- Do not log `customer_id` or `account_number` at INFO level or above.
- All routes under `/admin` must call `require_role("admin")` before any database read.
- Use `crypto.timingSafeEqual` for token comparison instead of `===`.

文档紧跟着强调:这些是给审查者的 guidance,不是确定性的 guardrail,不阻断写入,也不保证每处违规都被抓到。而且是只增不减的——写一条「忽略某类漏洞」并不能压制那类发现。

per-edit 那层的自定义模式写在 .claude/security-patterns.yaml,只列与写规则直接相关的几个字段:

字段类型说明
rule_namestring告警里显示的标识
regexstring对编辑内容做匹配的 Python 正则
substringslist字面子串,与 regex 二选一提供
pathslist可选 glob,规则只对匹配的文件生效
exclude_pathslist可选 glob,跳过匹配的文件

paths 有个反直觉的地方,文档专门写了:glob 是对完整文件路径匹配的,所以项目相对的模式要加 **/ 前缀。规则文件的查找位置分三档——用户级 ~/.claude/、项目级 .claude/(随仓库入版本控制)、以及项目本地的 .local.md 变体(个人覆盖用,文档建议加进 .gitignore),存在的都会加载并拼接,总量有上限。

还有一条容易漏读的:security-patterns 也支持 .yml.json,schema 相同,但文档写明 YAML 形式需要 PyYAML 可导入,而插件不会替你装,JSON 形式在任何 Python 安装上都能用。故障排查那节把「有 yaml 文件但 PyYAML 导不进来 → 文件被静默忽略」列为常见静默跳过原因之一。Windows 上如果 Python 是干净装的,直接用 .json 更省事。

想关掉某一层而保留其余,文档给的是一组环境变量:ENABLE_PATTERN_RULES=0 关 per-edit 匹配、ENABLE_STOP_REVIEW=0 关每轮结束的 diff 审查、ENABLE_COMMIT_REVIEW=0 关提交审查、ENABLE_CODE_SECURITY_REVIEW=0 一次关掉所有模型驱动的审查、SECURITY_GUIDANCE_DISABLE=1 整体停用但不卸载。运行诊断写在 ~/.claude/security/log.txt

前置条件别跳:文档写明需要 Claude Code CLI 2.1.144 或更高、PATH 上有 Python 3.7 或更高;agentic 的提交审查需要 3.10 以上,走第三方 provider(文档举的是 Amazon Bedrock 与 Google Cloud 的 Agent Platform)时所有模型驱动的审查都需要 3.10 以上。解释器查找顺序是先试 python3.13python3.10,再回退 python3pythonpy -3——最后那个是 Windows 的 launcher。首次运行会在 ~/.claude/security/ 建虚拟环境并装 Claude Agent SDK,需要 pip 和网络。

第三层:仓库里本来就有的代码,走 claude-security

前两层都有个共同盲区:它们只看这次会话产生的变更。你接手的那个祖传仓库里已经躺着的问题,谁都不看。这就是 claude-security 插件的位置——文档把它定位成「按需深扫」这一档。

它加一个命令 /claude-security,菜单下有三个 job:扫整个代码库、只扫一组变更、把发现变成补丁。前置条件比另一个插件严:文档写明需要 Claude Code v2.1.154 或更高且在付费计划上(因为扫描用到 dynamic workflows;Pro 上需要在 /config 的 Dynamic workflows 那一行打开),PATH 上有作为 python3 的 Python 3.9.6 或更高,Linux、macOS、Windows 都支持。Git 是变更扫描和出补丁所必需的,文档明说这两个 job 不支持其它版本控制系统;全量扫描在任何目录都能跑。

产物这块值得单说。每次扫描把结果写进仓库里一个带时间戳的 CLAUDE-SECURITY-<timestamp>/ 目录:报告 CLAUDE-SECURITY-RESULTS.md(每条发现带 ID、影响、利用场景、严重度、置信度和建议)、机器可读的 CLAUDE-SECURITY-RESULTS.jsonl,以及记录本次扫了哪个 commit 的 CLAUDE-SECURITY-REVISION-<commit>.json(不在版本控制下时盖 UNVERSIONED)。文档写明这个目录是扫描对你 checkout 做的唯一改动,而且它自带一份 .gitignore,随手一个 git add 不会把报告扫进提交;反过来要留档审计,就删掉那一个 .gitignore 再正常提交。

两条容易吃亏的限制:只有已提交的变更会被扫,手上没提交的先 commit 或 stash,或改跑读工作树的全量扫描;以及文档直说的——扫描是非确定性的,两次扫同一份代码可能给出不同发现。别把「扫过一遍没报」当成结论。

补丁那步同样明确:每个补丁在仓库的一份临时副本里起草,源文件不动;交付前由一个独立于起草者的 agent 复审,代码有测试时会跑测试。只有当复审能担保「确实修了那一条发现、没引入新漏洞、其余行为不变」三件事才会真的产出补丁,担保不了就给你一段说明。补丁从不自动应用,落在报告的 patches/ 目录,一条发现一个 F<n>.patch,由你自己在 shell 里应用:

git apply CLAUDE-SECURITY-<timestamp>/patches/F1.patch

文档建议每个补丁单独开一个 pull request。

三层之外还有什么,以及它们的接缝

除了上面三份,两个插件页的层级表里还并列了 /security-review(对当前分支跑一次性的安全检查)和 Code Review(在 pull request 上跑,文档标注为 Team 和 Enterprise 计划)。两个插件页各自都写明了同一层意思:它们不替代你已有的静态分析、依赖扫描这些既有工具,是并排跑而不是替换。

有两处接缝分散在不同页里,放一起才看得清。

一是 hooks。security-guidance 页说「要硬阻断得配一个会阻止编辑的 hook」,而 security 页在团队安全那节推荐用 ConfigChange hooks 审计或阻断会话中的设置更改——两处指向同一套机制。换句话说,唯一能真正「拦下来」的手段不在这三层里面,而在 hooks 和 CIsecurity-guidance 页也说明它整个插件就建在 hooks 上,注册了 SessionStartUserPromptSubmit、针对 Edit/Write/NotebookEditPostToolUseStop、以及过滤到 git commitgit pushPostToolUse

二是 MCP。security 页写得很直白:允许的 MCP 服务器清单配置在你签入版本控制的 Claude Code 设置里;Anthropic 会按其 listing criteria 审核 connectors 再收进目录,但不对任何 MCP 服务器做安全审计,也不管理它们。装第三方 MCP 服务器时,这句话就是你的责任边界。

回到最初那条路径:权限系统在动作发生之前决定它能不能做;security-guidance 在编辑落盘之后、每轮结束时、以及 Claude 提交时各查一遍;claude-security 管的是这条路径根本不覆盖的、仓库里已经存在的代码。三份文档、三个位置,配错了地方就是白配。

该产品迭代频繁,本文提到的命令、配置项、环境变量与版本要求随版本变动,以官方文档最新内容为准。


本文依据 Claude Code 官方文档(code.claude.com/docs)于 2026-08-17 的公开内容整理。 该产品闭源,本文只复述官方文档写明的机制,不推断其内部实现我们没有对文中涉及的功能做过实测,因此不涉及界面外观、操作手感与运行速度的任何描述。 该产品迭代频繁,文中涉及的命令、配置项与默认值随版本变动,请以官方文档最新内容为准。 本文不涉及价格、额度与限流的具体数值,相关信息请以官方定价与用量说明页为准。 安全与合规相关做法请结合自身环境评估,本文不构成安全方案建议。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。