Contents

Agent 的安全,不该是正则表达式

Agent 的安全,不该是正则表达式

最近在 Hacker News 上看到一篇文章,标题很直白:Stop Using OpenCode。作者 Wren 用了大约五千字,把 OpenCode 的设计缺陷和安全问题翻了个底朝天。HN 评论区 240 多条回复,吵得不可开交。

但让我留意的是一条被忽视的线索——这场争论里最有技术含量的部分,不是 bug 有多严重,而是一个更根本的问题:AI 编码工具到底该怎么处理安全?

纸糊的护栏

先看几个绕过 OpenCode 权限系统的例子:

echo 'git clean -fdx .' | bash
python3 -c "import shutil; shutil.rmtree('/')"
cat ~/.ssh/id_rsa | base64

OpenCode 用 tree-sitter 解析 bash 语法树,再用正则表达式匹配危险命令。听起来合理?实际上这些过滤全都能用管道、heredoc、base64 编码绕过。

更离谱的是持久化权限陷阱。你在 OpenCode 里对 python3 回复了"Always Allow",之后所有 python3 -c 命令都免检——包括读取你 SSH 私钥。文件权限过滤同样挡不住,shutil.rmtree("/") 照样畅通无阻。OpenCode 的默认行为就更吓人了:首次启动时输入一个字母回车,就能打通远程模型和本地 shell,模型 URL 从 models.dev 动态下载,也就是说——你不确认任何东西,就已经把完整系统访问权交给了互联网上的一段代码。

Wren 原话是这么说的:这不是护栏,这是祈祷。

17 万 Star 的工具,安全防护层的强度约等于一张写着"请勿乱动"的便利贴。

方向就错了

问题不在 tree-sitter 解析得准不准,也不在正则写得严不严。

问题在于:shell 是被设计出来执行任意命令的,在应用层拦截 shell,方向本身就不对。

HN 评论区有位叫 qarl2 的开发者,跟 Wren 有过一段技术交锋。qarl2 的主张是操作系统层面的方案——Linux 的 Landlock(restrict_self 系统调用)、OpenBSD 的 W^X(写时执行隔离)。这些是内核级的能力,应用层绕不过去。

区别在哪?正则过滤是在问"这行命令危不危险",内核隔离是在说"你只能碰这些文件"。前者需要穷举所有危险模式——永远做不到。后者从根本上限制了可达范围——不需要枚举。

评论区还有一位安全研究者叫 tptacek,他倒是比较冷静:安全问题确实严重,但工具本身的代码生成能力还是可用的,不该因为安全拉跨就否定整个项目。这个判断我部分认同。但话说回来,代码生成能力再强,如果有人通过权限漏洞把你仓库清空了,“但编辑器本身很好用"这种安慰也没人听得进去。

我原本想引用一句兵法来升华这段,但想了想,安全防护不需要兵法加持,说人话就行:安全不该靠聪明地识别攻击模式,该靠笨拙地限制可达空间。

不提供,反而是对的

HN 评论里有一条让我印象深刻的判断,来自叫 ekidd 的开发者:

“Agent 不该拥有它不需要的东西。”

换个说法就是:如果你不需要给 AI 编码工具 root 权限,就别给。给了,就别指望应用层能拦住它。

这正是 pi-agent 的设计思路。之前我写过一篇 OpenCode 与 Pi 的对比文章,里面提到一个核心差异:OpenCode 选择"什么都能干”——模型无关、全栈覆盖、内置沙箱;Pi 选择"什么都能改"——四条核心动作(读、写、编辑、执行),沙箱交给外部。

Pi 的哲学说白了就是:我不假装提供安全,所以我没有安全漏洞。

HN 评论里叫 zyuiop 的网友说得干脆:工具假装提供安全功能,不如完全交给外部专业沙箱。另一位高赞评论者 nylonstrung 说得更直接——Pi 已经完全替代了 OpenCode。原因不是 Pi 功能更多,恰恰是因为 Pi 更克制。不做的事情越多,出问题的面越小。

这个逻辑其实很朴素。你不会给实习生 root 权限然后装个软件限制他访问特定目录——你直接给他一个普通账号。安全靠限制能力边界,不靠在边界内装减速带。

OpenCode 的做法是:给你 root 权限,再套一层应用层过滤器。这跟在高速公路中间放减速带一样——总有车绕过去。

我自己跑 AI Agent 用的就是外部隔离——bwrap 或者 nono.sh 包一层,agent 在里面怎么折腾都出不来。工具内部那些权限弹窗?我基本当 confirm 键用。有些人用 Docker 容器,有些人用 firejail,原理都一样:在启动 agent 之前就把边界画死,别指望 agent 自己守规矩。

这跟企业管理是一个道理——制度约束比道德约束靠谱。你不会指望员工自觉不偷看薪酬数据,你会把权限设好。对 AI 也是一样。

写在最后

那篇 Stop Using OpenCode 里,最让我深思的不是具体的 bug,而是作者最后的判断——“LLM 用于代码生成是死路一条”。

这个结论太极端了。我不同意。AI 辅助编码这个方向没问题,问题在于工具怎么处理安全边界。内核隔离、最小权限、外部沙箱——这些原则在操作系统安全领域已经验证了几十年,AI 编码工具没有理由重新发明轮子。

作为用户,别依赖任何工具的内置权限系统。bwrap、nono.sh、sandbox-exec,这些才是真正的边界。工具内部的"安全功能",当个操作确认就行,别当护栏。

OpenCode 事件应该成为所有 AI 编码工具的警钟——你的 star 数再多,你的模型覆盖再广,如果安全边界是正则表达式画的,那它就是一张纸。好工具值得被严肃对待,而严肃对待的第一步,就是承认应用层安全这条路走不通。

说到底,安全是系统工程问题,不是正则表达式能解决的。