351 points高热度讨论,总结使用Claude Code时的安全风险和防范策略。对想充分发挥工具能力的程序员必读。
最近我越来越频繁地使用 Claude Code。后来我意识到,我并不会趁它运行时去做别的事情,而是会不停地查看它,看看是不是又在请求某项权限。这让我觉得,让 Agent 替我干活的意义似乎完全没有体现出来。因此,我想给 Claude Code 加上 --dangerously-skip-permissions flag。
如果你没用过,这个 flag 的作用正如其名:允许 Claude Code 随心所欲地执行操作,事先无须请求权限。不会再出现“我可以安装这个 package 吗?”“我应该修改这项 config 吗?”“我可以删除这些文件吗?”之类的问题。
这对保持工作流畅非常有帮助,因为我不用再担心它只是为了询问权限,就停下手里的工作。
但你也知道,这很危险。
我希望自己的 filesystem 完好无损,所以显而易见的解决方案,就是不要让它直接运行在我的 OS account 下。
我的第一反应是:把它扔进 Docker container。container 不就是用来做 isolation 的吗?
问题是,我希望 Claude 能够构建 Docker image、运行 container,甚至编排一些东西。
这样一来,你就需要 Docker-in-Docker,也就意味着要使用 --privileged mode,而这会彻底违背 sandboxing 的初衷。你相当于把“Claude 可能会弄坏我的 filesystem”,换成了“Claude 对我的 container runtime 拥有 root-level access”。
除此之外,还有嵌套网络带来的各种怪问题、让人开始怀疑人生的 volume mounting permission,以及一种挥之不去的感觉:你不是在使用工具,而是在和工具较劲。
我还短暂考虑过下面这些方案:
#yolo,直接在 bare metal 上运行:不行,不行,还是不行
sandbox-runtime:这更像是一种 ACL 方案。我希望 Claude 能做任何事情,因为除了代码之外,它本来就接触不到其他东西
firejail 或类似工具:和 Docker-in-Docker 存在同样的问题
手动搭建 VM:可行,但很繁琐,而且不可复现
cloud VM:要花钱、有延迟,还得把代码上传到某个地方
然后,我想起了一个在 Docker 风靡之前就用过的项目:Vagrant。
如果你没有经历过那个年代,Vagrant 可以通过一份可复现的 config file,为你提供真正的 VM isolation。它基本上就是面向本地开发环境的 infrastructure as code。
完整的 VM isolation(不共享 kernel)
可以轻松销毁并重新构建
shared folder 让使用体验足够接近本地环境
没有 Docker-in-Docker 那些麻烦事
这些年来,Docker container 一直能够满足我的全部需求,所以我已经很多年没用过 VirtualBox 了。直到现在,我才下载了最新版本(7.2.4),开始动手搭建。
第一次执行 vagrant up,结果……VM 明明完全处于 idle 状态,CPU 占用却一直保持在 100% 以上。
我花了一个小时关闭各种 VM feature、调整 settings、在 Google 和 LLM 上尝试各种包含“virtualbox high cpu idle”的关键词组合——你懂的,常规操作。
最后,我找到了一个 GitHub issue。VirtualBox 7.2.4 发布时带有一项 regression,会导致处于 idle 状态的 guest 出现很高的 CPU usage。怎么偏偏就让我碰上了。
下面是我这份简单的 Vagrantfile:
vm_name = File.basename(Dir.getwd)
Vagrant.configure("2") do |config|
config.vm.box = "bento/ubuntu-24.04"
#config.vm.network "forwarded_port", guest: 3000, host: 3000, auto_correct: true
config.vm.synced_folder ".", "/agent-workspace", type: "virtualbox"
config.vm.provider "virtualbox" do |vb|
vb.memory = "4096"
vb.cpus = 2
vb.gui = false
vb.name = vm_name
vb.customize ["modifyvm", :id, "--audio", "none"]
vb.customize ["modifyvm", :id, "--usb", "off"]
end
config.vm.provision "shell", inline: <<-SHELL
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y docker.io nodejs npm git unzip
npm install -g @anthropic-ai/claude-code --no-audit
usermod -aG docker vagrant
chown -R vagrant:vagrant /agent-workspace
SHELL
end
cd ~/my-project
vagrant up
vagrant ssh
claude --dangerously-skip-permissions
# tell Claude what you want and let it run wild with no babysitting
首次启动需要几分钟来 provision 所有内容,而且每个项目都需要登录一次 Claude。但完成这些操作之后,vagrant up 就会非常快。
然后,当你结束一天的工作时:
exit
vagrant suspend
那么,获得这些新权限之后,Claude 能做些什么?
因为它运行在 VM 中,所以我还给了它 sudo access,并明确告诉它拥有执行任何操作的权限:安装 system package、修改 config、创建文件、运行 Docker container,什么都可以。
手动启动一个 webapp API,并通过 curl request 对其进行检查
安装 browser,手动检查应用,然后根据检查结果构建 end-to-end test
配置 postgres database、运行测试 SQL、验证 db migration 是否正常工作,等等
构建并运行 Docker image
如果是在 host machine 上执行这些操作,我会非常不放心,尤其是在启用了那个“just do it” flag 的情况下。
现在,我觉得 Claude 的工作效率高多了,因为它获得了更多 context。它不再需要依赖我来运行 command、把 output 或 error message 返回给它,然后再继续迭代。它自己就能完成这一切。
Claude Code 算不上 resource hog,而 VM 也有充足的性能余量。shared folder sync 运行良好,文件发生变化时没有延迟,也没有出现奇怪的问题。这是在 Linux 和 VirtualBox 环境下的体验,其他 platform 上的情况可能有所不同。
你能够防范的是:
意外的 filesystem damage
过于激进的 package installation
你没有察觉到的 configuration change
各种“糟了,我不是想让 Claude 做这个”的情况
你无法防范的是:
删除实际的 project,因为 file sync 是双向的
恶意 AI 试图逃逸 VM(VM escape vulnerability 确实存在,但非常罕见,而且需要刻意利用)
来自 VM 的 network-level attack 或误操作
data exfiltration:VM 仍然可以访问互联网,不过除了代码之外,理论上也不该有什么可供外泄的数据
Threat model:当我进入专注状态、只想赶紧把东西做出来时,我不相信自己每次都能及时发现 Agent 正在做什么。这套方案的目标是防止意外,而不是抵御复杂攻击。
由于我的所有项目都使用 git 管理,所以即使它把项目里的某些东西弄坏了,我也不在乎。此外,你还可以继续使用平时熟悉的 git tooling、flow 或其他任何东西,无须把 credential 添加到 VM 中。
不过,如果你需要更严格的方案,config.vm.synced_folder 也支持 type: "rsync"。它会在 Vagrant 启动 machine 时,将运行 Vagrant 的 machine 上的数据一次性单向同步过去。但之后如何同步回来,或者还需要执行哪些操作,就得由你自己负责了。
这套方案花了一些时间才调整到位,主要是因为 VirtualBox 的 CPU bug。不过现在,它用起来已经毫无阻碍。我可以放心地让 Claude Code 做任何它想做的事情。如果哪里出了问题,直接销毁 VM,重新开始即可。
Vagrantfile 很短,而且可复现。把它放进任意 project directory,执行 vagrant up,你就拥有了一个 sandbox。
如果你正在给 Claude Code 使用那个危险的 flag,我建议采用类似的方案。即使你每次审批操作时都很谨慎,也只需要一次疏忽,就可能把事情搞砸。