ClaudeClaude Code

Claude Code 的安全机制一览,和六种隔离方案怎么选:权限、沙箱、容器、虚拟机各挡住什么

权限决定一个动作能不能做,隔离决定它做了之后够得着什么。这篇把 Claude Code 内置的防护、防提示注入的几道关、MCP 和云端会话各自的要点放在一起,再比较六种隔离方案:内置的 Bash 沙箱、sandbox runtime、dev container、自定义容器、虚拟机、云端会话。

发布 · 约 18 分钟读完 · 经人工审核()· 本站的内容怎么来的

本文根据公开分享整理,本站尚未实测。操作前请对照文末的原始来源。

本页目录(11 节)
  1. 一、两层:权限和隔离
  2. 二、内置的防护
  3. 三、防提示注入
  4. 四、MCP、云端会话、Remote Control
  5. 五、六种隔离方案
  6. 六、按目的选
  7. 七、隔离和权限模式怎么配
  8. 八、各个方案的要点
  9. 九、在组织里强制执行
  10. 十、平时的做法
  11. 这篇没有实测的

这篇解决两个问题:

  1. Claude Code 自带哪些防护? 它们各自挡的是什么,挡不住什么?
  2. 想把它关在一个隔离的环境里跑,有哪几种办法,怎么选?

这篇整理自官方的两页文档。第八节里的 sandbox runtime 是本站在服务器上实测的,其余没有逐项实测。内置的 Bash 沙箱本站另外单独测过,见《Claude Code 沙箱怎么配》;权限模式见《权限模式怎么选》。

一、两层:权限和隔离

先分清两个概念,后面所有内容都建立在这上面。

管什么 例子
权限 一个动作能不能做,做之前要不要先问你 权限模式、allow 和 deny 规则
隔离 一个命令跑起来之后能读写什么、能连到哪 Bash 沙箱、容器、虚拟机

两层是配合着用的:权限模式放手让动作不问就做的时候,隔离的边界限制这些动作够得着的范围。

权限这一层

会话的权限模式决定 Claude 哪些动作可以不先问你。交互式的终端会话和 VS Code 会话,内置的起始模式是 auto。

  • auto 模式:由另一个分类器模型代替你审每个动作,它判断不安全的就拦下。你明确写的 ask 和 deny 规则仍然生效,组织可以把 auto 模式关掉。
  • Manual 模式:从只读权限起步。要改文件、跑测试、执行命令时先问你,你可以批准这一次,也可以从此都允许。ls、cat、git status 这类内置的只读命令不用问。

文档里有一句话要记住:批准之前审查代码和命令是用户自己的责任。

二、内置的防护

防护 做什么 要留意的
Bash 沙箱 用文件系统和网络隔离来跑 Bash 命令,减少询问又不放松安全。用 /sandbox 配 只管命令,见第五节
工作目录边界 Manual 模式下,文件工具要读写启动目录以外的地方时先问你 这是一道询问,不是硬边界。 你批准的 Bash 命令照样能写你这个系统用户能写的任何地方
常用命令的允许清单 把常用的安全命令加进允许清单,可以按个人、按代码库、按组织设
accept edits 模式 自动批准文件编辑,以及工作目录内的几个文件类命令:mkdir、touch、rm、mv、cp、sed 别的 Bash 命令和目录外的路径仍然要问

工作目录边界那一条最容易被误解。想不经询问读某个目录,把它加成额外的工作目录;想在操作系统这一层限制 Bash 命令,要开沙箱。

三、防提示注入

提示注入是指有人把恶意的文字塞进 Claude 会读到的内容里,想改掉它原本的指令。Claude Code 有这几道关:

防护 具体是什么
权限系统 Manual 模式下,敏感的操作要你明确批准
联网命令要批准 curl、wget 这类从网上取内容的命令默认不自动批准
联网的工具要批准 Manual 模式下,大多数会发网络请求的工具默认要你批准
网页先过一遍 大多数情况下,WebFetch 先用一次单独的模型调用处理网页,Claude 拿到的是那次调用的回答,不是原始网页
信任确认 交互式会话在一个没有信任过的目录里启动时,显示工作区信任对话框。项目的 .mcp.json 里的服务器另有自己的批准提示
命令注入检测 Manual 模式下,分析不透的 Bash 命令要先问你
匹配不上就问 Manual 模式下,没有规则匹配的命令默认要批准
凭据的保存 macOS 上存在钥匙串里;Linux 上是权限 0600 的文件;Windows 上是沿用用户目录访问控制的文件

四处细节

一、deny 规则是按命令的字面匹配的。 想不让 Claude 跑 curl,可以把它写进 permissions.deny。但规则认的是命令怎么写的,换一种写法可能就匹配不上。要一种不依赖命令文字的网络限制,用沙箱的网络隔离。

二、-p 会话不显示信任对话框,也不显示 .mcp.json 的批准提示。 两个都没有。在一个不信任的仓库里跑 claude -p 之前,先弄清楚这个仓库里的文件能让它执行什么。

三、直接在家目录里启动,信任只在这一次会话里有效,不写到磁盘,每次启动都会再问,也没有设置能让它记住。从项目的子目录里启动,信任才会按目录保存。

四、只允许了命令的一部分,跳不过注入检测。 写了 Bash(git *) 这样的 allow 规则,遇到分析不透的命令照样会问。在沙箱里跑的命令可以不经过这一道。

Windows 上的一条提醒

官方建议不要启用 WebDAV,也不要让 Claude Code 访问可能含有 WebDAV 子目录的路径(比如 \\*)。微软已经因为安全风险弃用了 WebDAV;启用它可能让 Claude Code 绕过权限系统向远程主机发请求。

处理不可信内容的五条做法

  1. 批准之前看清楚建议的命令。
  2. 不要把不可信的内容直接用管道喂给 Claude。
  3. 对关键文件的改动要核对。
  4. 跑脚本和调用工具用虚拟机,尤其是要和外部的网络服务打交道的时候。
  5. 发现可疑的行为,用 /feedback 报告。

文档自己也说了:这些防护能明显降低风险,但没有哪个系统能挡住所有攻击。

四、MCP、云端会话、Remote Control

MCP

  • 项目范围的服务器定义在 .mcp.json 里,可以提交进仓库。但只看 .mcp.json 看不全:别的范围的服务器、claude.ai 上的连接器是在仓库外面配的,插件也能带服务器进来。
  • 官方建议自己写 MCP 服务器,或者用你信得过的提供方的。
  • Anthropic 在把连接器收进自己的目录之前会按上架标准审一遍,但不对任何 MCP 服务器做安全审计,也不负责管理它们。

MCP 怎么接、三个范围怎么选,见《Claude Code 接 MCP 服务器实战》。插件带进来的东西怎么审,见《插件进阶(上)》。

云端会话

在 Anthropic 托管的环境里,云端会话另有这些控制:

控制 内容
隔离的虚拟机 每个云端会话跑在一台独立的、Anthropic 管理的虚拟机里
网络访问 默认受限,可以配成完全关闭,或者只允许指定的域名
凭据保护 GitHub 的凭据加密存在 Anthropic 的服务器上,不进会话的虚拟机。虚拟机里只有一个限于本次会话的短期凭据,GitHub 的流量经过 Anthropic 的代理,由代理在服务端带上凭据
推送限制 代理拒绝删除分支,也拒绝推送分支以外的东西(比如标签)。哪些分支能更新,由你仓库的分支保护规则决定
审计日志 云端会话里的所有操作都有记录
自动回收 会话的虚拟机闲置一段时间之后回收
删除 随时可以删掉一个会话

推送限制有一处要留意:你连接的那份 GitHub 权限如果能绕过某条分支保护规则,这条规则就挡不住会话的推送。

组织把会话转到自托管环境时,跑在你们自己的机器上,隔离、出网和 git 凭据都由你们的部署负责。

云端会话怎么用,见《云端会话》。

Remote Control 不一样

Remote Control 是网页端连到一个跑在你本机的 Claude Code 进程:

  • 代码的执行和文件的访问都留在本机,没有云端的虚拟机,也没有沙箱。
  • 会话的流量经 Anthropic API 走 TLS。
  • 连接期间,会话的记录存在 Anthropic 的服务器上,用来在几台设备之间同步对话。

用法见《Remote Control 和手机》。

五、六种隔离方案

隔离限制一个会话能读什么、写什么、连到哪。下面三种情况最需要它:让 Claude 少问就干活、无人值守地跑、让它处理你不完全信任的代码。

方案 隔离的是什么 要 Docker 吗 配置的工作量
内置的 Bash 沙箱 Bash、PowerShell 和 Monitor 工具跑的命令及其子进程 不要 macOS 上最少;Linux 和 WSL2 上少
sandbox runtime 整个 Claude Code 进程,包括文件工具、MCP 服务器和 hooks 不要 少
dev container 整个开发环境 要 中等
自定义容器 整个开发环境 要 中等到多
虚拟机 整个操作系统 不要 多
云端会话 整个操作系统,由 Anthropic 托管 不要 不用配;要 Claude 订阅

前两种直接跑在主机的操作系统上,不用容器。其余的把 Claude Code 放进容器或虚拟机。

最关键的一条区别

内置的 Bash 沙箱只限制 Bash 命令。 内置的文件工具、MCP 服务器和 hooks 仍然直接跑在你的主机上。表里其余每一种方案,都是把整个 Claude Code 进程放进隔离边界,文件工具、MCP 服务器和 hooks 也一起受限。

具体地说,Bash 沙箱管不到这些:

  • Read、Edit、WebFetch 这些内置工具跑在 Claude Code 进程里面,不会启动任意代码,由路径和域名的权限规则来管。
  • MCP 服务器、命令型的 hook、插件的监视器是单独的进程,在主机上不受约束地运行。

两条不要忘

  • 隔离降低的是出事之后的影响,不是把风险变成零。 只要允许出网,代理读得到的数据就可能被带出去;只要项目目录是可写挂载的,里面的代码就可能被改。
  • 隔离不改变发给模型的内容。 你的提示词和 Claude 读过的文件,有没有沙箱都会发给 Anthropic API 或者你配的供应商。发了什么、怎么减少,见《Claude Code 的网络和数据》。

六、按目的选

你想 从哪开始
在自己的机器上日常干活,少点询问 内置的 Bash 沙箱,用 /sandbox 配
用 --dangerously-skip-permissions 或 auto 模式让它无人值守地跑 官方预配好的 dev container、任意容器或虚拟机,或者 sandbox runtime
不用 Docker,把 MCP 服务器和 hooks 也一起隔离 sandbox runtime
处理一个不信任的仓库 一台专用的虚拟机;有 Claude 订阅的话也可以用云端会话
给整个团队统一一个带沙箱的环境 官方预配好的 dev container,复制到你们的仓库里
从一台没有本地环境的设备上用 云端会话
要求组织里每个开发者都隔离 见第九节
主机是原生 Windows 容器或虚拟机,或者在 WSL2 里用 Bash 沙箱

七、隔离和权限模式怎么配

--dangerously-skip-permissions:Claude 不问就做,没有询问来拦住错误,这时候保护系统的只有你选的隔离边界。官方的要求是:带这个参数的会话一律放在容器、虚拟机或 sandbox runtime 里,这样文件工具、MCP 服务器和 hooks 也在边界里面。另外在 Linux 和 macOS 上,用 root 身份带这个参数,Claude Code 会拒绝启动,所以容器里也要用普通用户跑。

auto 模式:用分类器代替询问。分类器是对每个动作的控制,不是隔离边界。所以隔离对无人值守的 auto 模式是多加的一层防护,不像上一种那样必须有。

只有 Bash 沙箱,不够无人值守。 它只约束 shell 命令,两种模式下都一样。

可以叠着用。 在容器或虚拟机里再开 Bash 沙箱,外面一层环境边界,里面一层按命令的限制。没有特权的容器里要设 enableWeakerNestedSandbox 才开得起来。

八、各个方案的要点

内置的 Bash 沙箱

内置在 Claude Code 里,用操作系统自带的机制限制命令的文件系统和网络访问。运行 /sandbox 打开面板选模式。不支持原生 Windows,Windows 上用 WSL2 或下面的容器、虚拟机方案。

安装、默认的边界、怎么放宽和收紧、命令什么时候会跑到沙箱外面,本站都测过,见《Claude Code 沙箱怎么配》。

sandbox runtime(本站实测)

@anthropic-ai/sandbox-runtime 这个包,用和内置沙箱同一套机制(macOS 上的 Seatbelt,Linux 上的 bubblewrap)把一整个进程包起来。通过它启动 Claude Code,会话的工具、hooks 和 MCP 服务器就都受约束了。它目前是 beta 阶段的研究预览,配置格式还可能变。

这一小节是本站在服务器上跑出来的,标了“文档”的几处除外。

实测环境
日期 2026-10-13
版本 sandbox-runtime 0.0.79,Claude Code 2.1.296,bubblewrap 0.9.0,ripgrep 14.1.0,Ubuntu 24.04
做法 一个示例项目加几份配置。先在沙箱里跑 shell 命令看边界,再把 Claude Code 放进去跑了三次

依赖。 Linux 和 WSL2 上要 bubblewrap 和 socat(和内置沙箱一样),再加 ripgrep。Claude Code 自己带着 ripgrep,但独立运行的 runtime 要从 PATH 里找,本站是用 apt install ripgrep 装的。macOS 上不用另外装(文档)。

不配置就启动,会怎样

配置默认放在 ~/.srt-settings.json,也可以用 --settings 指定一个文件。没有这个文件,它照样能启动。 在里面跑几条命令(输出是节选,第一行是测试脚本自己打的):

启动了,cwd=/home/ccdemo/demo/h34-srt/proj
touch: cannot touch 't1.txt': Read-only file system
curl: (56) CONNECT tunnel failed, response 403

连当前的项目目录都写不了,网络全断。这种状态下试了四处:~/.npm/_logs 和 ~/.claude/debug 能写,项目目录和 /tmp/claude 不能(后一个在这台机器上本来就不存在)。所以**“启动成功”不代表你的设置生效了**。

反过来,用 --settings 指了一个有问题的文件,它拒绝启动,退出码 1:

文件的情况 报错
不存在 … does not exist. Refusing to run with the built-in defaults
是空的 … is empty. Delete it, or put a config in it.
不是合法的 JSON … is not valid JSON: Unexpected end of JSON input

一份能让 Claude Code 跑起来的配置

本站的实测环境走的是酷站AI 的接口,下面是跑通的那一份:

{
  "network": {
    "allowedDomains": ["api.koozhan.com", "api.anthropic.com"],
    "deniedDomains": []
  },
  "filesystem": {
    "denyRead": [],
    "allowWrite": [
      "/home/ccdemo/demo/h34-srt/proj",
      "/home/ccdemo/.claude",
      "/home/ccdemo/.claude.json",
      "/tmp"
    ],
    "denyWrite": [
      "/home/ccdemo/demo/h34-srt/proj/.claude/settings.json",
      "/home/ccdemo/demo/h34-srt/proj/.claude/settings.local.json"
    ]
  }
}

每一项的来由:

  • 写:项目目录;Claude Code 的配置路径 ~/.claude 和 ~/.claude.json;它写运行时文件的 /tmp(macOS 上是 /private/tmp,文档)。
  • 域名:你的接口地址。直连官方就是 api.anthropic.com;用第三方供应商或中转站时写它的域名,api.anthropic.com 也留着,WebFetch 的域名安全检查默认还会访问它(文档)。用 claude.ai 账号登录的,再加 claude.ai 和 platform.claude.com(文档)。
  • denyWrite:项目里的两个设置文件,原因见下面“四处要留意”的第二条。

启动时把 claude 当成要包起来的命令:

npx @anthropic-ai/sandbox-runtime --settings ./srt.json claude

实测在里面跑 claude -p "只回复 ok",正常返回。请求是经 runtime 的代理发到中转站的:沙箱里 HTTP_PROXY、HTTPS_PROXY 这几个环境变量都被设好了。

同一条命令也可以用来把单独的 MCP 服务器或别的辅助进程关进沙箱(文档)。

文件工具和 hook 也被关住了

这是它和内置 Bash 沙箱的区别所在,两样都测了。

hook。 项目里放一个 SessionStart 的 hook,脚本里往项目外面写一个文件,把结果记下来。不带沙箱跑一次,再放进 runtime 跑一次:

hook 记下的退出码 项目外的那个文件
不带沙箱 0 出现了
放进 runtime 1 没有出现

Write 工具。 在沙箱里带 --dangerously-skip-permissions,让 Claude 用 Write 工具写三个地方,它的报告:

1. 失败:EROFS: read-only file system, open '/home/ccdemo/demo/h34-srt/outside/from-claude.txt.tmp.2.610038377f5b'
2. 成功:已创建 /home/ccdemo/demo/h34-srt/proj/from-claude.txt
3. 失败:/home/ccdemo/demo/h34-srt/proj/.mcp.json exists but is not a regular file (a device, FIFO or socket). Write only creates or overwrites regular files.

权限全放开了,项目外面仍然写不进去,项目里的 .mcp.json 也写不了。事后在主机上核对,只有第二个文件存在。

边界一览

用一份只放开项目目录和一个域名的配置,在沙箱里逐项试:

操作 结果
在项目里建文件 成功
写项目外的目录、家目录、/tmp 失败,Read-only file system
写 .mcp.json、.bashrc 失败,Permission denied
写 .git/hooks/、.git/config 失败
建 .claude/commands/、.claude/agents/、.vscode/ 失败
读项目外的普通文件 成功
读 denyRead 里列的文件 失败,Permission denied
访问放行的域名 200
访问别的域名 失败,CONNECT tunnel failed, response 403

第三到第五行是它不用配置就会拦的:这些路径在项目目录里,项目目录又是放开的,照样写不了。按它的 README,denyWrite 优先于 allowWrite;读的规则相反,allowRead 优先于 denyRead(后一条没有测)。

四处要留意

一、默认什么都能读,包括放凭据的文件。 读是“默认全放开,列出来的才拦”。实测沙箱里读得到 ~/.claude/settings.json。用 API key 或中转站的人,凭据就在这个文件里,Claude Code 自己要读它,沙箱里跑的别的命令也读得到。能拦住它外泄的是网络那一层:只能连到你放行的域名。所以放行的域名越少越好,别为了省事放开通用的文件托管或粘贴类网站。

二、项目里的设置文件默认是可写的。 自动保护的清单里有 .claude/commands 和 .claude/agents,没有 .claude/settings.json。实测项目里本来就有 .claude/ 目录时:

改 .claude/settings.json          => 成功
新建 .claude/settings.local.json   => 成功
新建 .claude/skills/x/SKILL.md     => 成功
新建 .claude/commands/a.md         => 失败

设置文件里能放 hook。沙箱里的会话往里面写一个,下次你不带沙箱启动时它就不受约束地运行了。把这两个文件加进 denyWrite 之后再试,两个都写不了。上面那份配置里的 denyWrite 就是为这个。

顺带一个现象:项目里没有 .claude/ 目录时,整个 .claude 在沙箱里是只读的,里面什么都建不了。按 README 的说法,要保护的路径还不存在时,它会把缺的那一层整个挡住。

三、嵌套仓库只保护到一层深。 项目里还有别的 git 仓库时,它们的 .git/hooks 保护到哪一层,看 mandatoryDenySearchDepth,默认是 3:

写哪里 默认 设成 5
sub/.git/hooks/x(一层深) 失败 失败
vendor/lib/.git/hooks/x(两层深) 成功 失败

仓库放得深的项目,比如 monorepo 或者带着第三方仓库的,把这个值调大。按 README,它的范围是 1 到 10,越大启动时扫得越慢。

四、Linux 上的保护是启动时定下来的。 两个实测到的后果:

  • 会话当中新建的仓库不受保护。 在沙箱里 git init newrepo,再写 newrepo/.git/hooks/x,成功了。文档说 macOS 上是写入时才检查,新建的也管得到。
  • 放开的路径如果启动前不存在,就建不出来。 配置里放开了一个还不存在的目录,沙箱里 mkdir 它,报 Read-only file system。所以全新的环境里,第一次启动之前先把 Claude Code 的配置路径建好:
mkdir -p ~/.claude && { [ -f ~/.claude.json ] || echo '{}' > ~/.claude.json; }

无人值守地跑完之后,检查一遍你保持可写的那些路径。Linux 上还要检查会话新建的东西。

dev container

把 Claude Code 跑在一个由 VS Code 或兼容的编辑器管理的 Docker 容器里,项目挂载进去。可以在仓库里放一个 .devcontainer/ 目录自己定义。

claude-code 仓库里有一个示例,带一个默认全拒绝的 iptables 防火墙,可以拿来做起点:复制到自己的仓库,再调整防火墙的允许清单、基础镜像和固定的 Claude Code 版本。因为防火墙挡住了没批准的出网,这种配置下可以带 --dangerously-skip-permissions 无人值守地跑。

自定义容器

在任意的 Docker 或 OCI 镜像里跑,网络策略、挂载的卷、seccomp 配置都自己定。已经有容器基础设施或 CI 机器的组织最常走这条路。

不管容器是自己的还是托管服务的,都要检查三样:哪些东西是可写挂载的,容器里够得着哪些凭据和令牌,出网策略放行了什么。

虚拟机

专用的虚拟机隔离得最彻底,有自己的内核。可以是云上的实例、本地的虚拟化软件,或者 Firecracker 这类微型虚拟机。适合这几种情况:评估不可信的代码;安全策略要求代理和主机之间有内核级的隔离;主机层面的方案都达不到合规要求。

文档提到 Docker Sandboxes:它提供一个带自己的 Docker 守护进程和工作区同步的微型虚拟机,是 Docker 出的免费独立产品,不需要 Docker Desktop。

云端会话

跑在 Anthropic 托管的隔离虚拟机里。一个网络代理执行默认的允许清单,另一个代理把你的 GitHub 令牌留在沙箱外面,只给里面发有范围限制的凭据。

想要完整的虚拟机隔离又不想自己准备机器,或者要从一台没有本地开发环境的设备上派活,用它。要 Claude 订阅。一般还要连接 GitHub 账号,这样沙箱才能克隆你的仓库;从命令行用 claude --cloud 启动时,Claude Code 可以把本地的仓库打包上传,不需要 GitHub。

九、在组织里强制执行

开发者个人可以选用上面任何一种。组织能强制到什么程度,各个方案不一样:

方案 能不能强制,怎么做
内置的 Bash 沙箱 Claude Code 自己能强制的只有这一种。 把 sandbox 的设置项通过托管设置下发:设备管理工具管理的文件,或者 claude.ai 上的服务器托管设置
dev container 把示例提交进仓库可以统一环境,但这只是约定,不是强制的边界,因为 Claude Code 并不要求有容器。不许在容器外面跑,要靠组织的设备管理或软件白名单
自定义容器和虚拟机 通过批准的镜像分发 Claude Code,再用设备管理或软件白名单防止在镜像外面安装

十、平时的做法

处理敏感代码时:

  • 批准之前看完所有建议的改动。
  • 敏感的仓库用项目专属的权限设置。
  • 想多一层隔离,把整个 Claude Code 进程放进 sandbox runtime 或 dev container。
  • 定期用 /permissions 检查权限设置。

团队:

  • 用托管设置落实组织的规范,见《设置文件》。
  • 把批准过的权限配置放进版本控制里共享。
  • 用 OpenTelemetry 指标监控使用情况,见《用 OpenTelemetry 看用量》。
  • 用 ConfigChange hook 审计或者拦截会话当中的设置改动。

发现了 Claude Code 的安全漏洞: 不要公开披露;通过 Anthropic 的 HackerOne 项目报告,附上详细的复现步骤,在公开之前留出修复的时间。

另外两个和代码安全有关的工具,本站都测过:安全指导插件让 Claude 在会话当中检查并修复自己改动里的漏洞;Claude Security 插件扫描整个代码库。

这篇没有实测的

  • 除了 sandbox runtime,都是整理。 dev container、自定义容器、虚拟机没有在本站的服务器上装过、跑过。
  • sandbox runtime 只在 Linux 上测过,macOS 上的行为照文档写。放进去的是 Claude Code 的文件工具和一个 hook;MCP 服务器没有单独测。把 ~/.claude/settings.json 加进 denyRead 会怎样也没有测。三次模型调用,Claude Code 自己估算合计约 0.43 美元。
  • 内置的 Bash 沙箱测过,在另一篇里,那一篇是 Linux 上的结果。
  • 提示注入的防护没有做攻击测试。 表里写的是官方的说法。
  • 云端会话和 Remote Control 的安全控制没有验证,实测环境没有 claude.ai 账号。
  • sandbox runtime 是 beta,配置格式可能变,用之前以它仓库里的 README 为准。

来源

通过 API 中转站使用这些模型?到 Veridrop 免费检测中转站给你的是不是它声称的模型,或者看看中转站排行榜前 100 名。

相关文章