返回资讯中心
外部精选
软件工程
#开发者实时流

AI编码助手在真实机器上验证删除命令漏洞,误删用户主目录

来源标题:The test that deleted my home folder

一个AI编码助手为验证修复测试,在真实机器上运行未修复的旧代码,结果10秒内删除了用户主目录。该漏洞源于/delete命令接受../..路径,可逃逸数据目录删除任意文件。作者事后完整复盘了事件经过、损失及后续改进措施。

Hacker News 最新lisneanucristia2026/11/5 · 昨天19 分钟阅读

以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。

一个AI助手在真实机器上运行了一个危险的bug,以此证明它确实存在。以下是完整的取证过程、代价以及我做的改变。

一个周六的早晨,大约10秒钟内,我的主文件夹消失了。不是磁盘故障,不是勒索软件。是一次测试。

一个AI编程助手正在修复我构建的一个命令行工具中的bug——那是我自己的本地AI agent。这个bug很严重:一个/delete命令接受像../..这样的路径,可以逃出它的数据文件夹,删除远在它之外的东西。助手写了一个修复和一个测试。然后,为了证明这个测试确实能捕获这个bug,它把旧的、未修复的代码放回去,对这段代码运行了测试。

在真实机器上。在我的真实主文件夹里。

测试完全按照它被编写来证明的那样执行了:旧代码沿着路径逃出了沙箱,删除了我的用户账户能删除的一切。这篇文章是完整的故事:它是怎么发生的,我后来如何找到确切的命令,代价是什么,以及我做了什么改变,让这种事不会再发生。

删除运行了大约十秒钟,移除了我的用户能删除的一切:

换句话说,文件权限是我唯一的保护,而它们恰好保护了它们被设定要保护的东西。每一个权限过宽的文件夹都是一个漏洞。

起初这是个谜:没有攻击者,没有崩溃,明显的日志里什么都没有。调查花了将近一天。

从我的主文件夹读取文件的服务记录了它们最后一次成功和第一次失败。一个服务在10:12:16成功读取了一个脚本,第一个“文件未找到”出现在10:12:27。删除就发生在这十一秒之内。

恰好有两类位置被击中:主文件夹和临时文件夹,外加我的用户能解除链接的其他任何东西。root所有和容器所有的文件幸存了下来。所以删除是以我的用户身份运行的,不是root。

计划任务、agent自己的后台任务、监控exporter、沙箱化的辅助程序、MCP服务器:每一个都对照其日志和代码做了检查。在那个时间窗口内,没有任何一个运行了破坏性操作。

有两个AI助手会话处于活跃状态。一个在做网络研究。另一个在修复我的agent命令行工具中的两个路径处理bug。来自那个会话的一条shell命令在10:12:07启动,运行了超过两分钟,存活时间超过了删除窗口。紧接着,该会话报告它不再处于登录状态:它自己的凭证文件刚刚被删除了。

该会话的记录在主文件夹里,所以也没了。但已删除的数据会留在磁盘上,直到被覆盖。在原始磁盘上扫描该工具调用的唯一标识符,恢复了丢失记录的351条记录,包括确切的命令:

恢复的测试文件甚至用自己的话描述了那个bug:/delete ..命令清除了agent的数据文件夹,/delete ../..清除了主文件夹。测试用..、../..、../../..和/这样的路径调用了delete命令。fixture把一个数据文件夹重定向到了临时位置,但旧代码至少从真实主目录解析了一个路径。

损害还没有结束。3个MySQL数据库的数据文件夹被设置为我的用户可组写。它们的核心文件被删除了,但MySQL继续在已经打开的文件句柄上运行,所以一切看起来都正常。

第二天第一次重启,让已删除的文件真正消失了。三个数据库都无法启动。它们从几小时前取的夜间SQL转储中恢复——那是唯一在正常工作的备份。损坏的文件夹被放在一边用于对比。

教训中的教训:一个正在运行的进程可以隐藏删除,直到它重启。在这样的事故之后,趁你还在恢复模式时故意重启,而不是几周后措手不及。

机器的大部分是从不在主文件夹里的东西重建的:

真正丢失的是那些只存在于一个地方的东西:本地笔记、一些从未提交的脚本、桌面设置,以及助手的会话历史。

现在的规则是绝对的:任何涉及删除、路径遍历或任何写入自己文件夹之外的东西的测试,都在一个一次性容器中运行,无法访问真实主文件夹,最好没有网络,根文件系统只读。如果它逃出了沙箱,它摧毁的是一个空容器。

证明一个测试在旧代码上失败是好的做法。在宿主机上做就不是。

测试隔离了一个配置的数据文件夹。bug用了不同的路径。针对路径遍历bug的测试必须假设被测代码会去够真实路径,所以环境必须让那些路径无害:一个假的主目录、一个假的临时文件夹、一个容器。

助手在自动批准shell命令的情况下运行,在一台充满不可替代状态的机器上。我仍然每天使用AI助手,但是:

助手的错误仍然是我的错误。它用我的权限在我的机器上运行。

主文件夹现在每晚有加密、去重的备份到独立存储,外加一个新鲜度检查,当任何备份集比它应该的旧时提醒我。事故之前,主文件夹备份已经在11个月前悄悄停止了。没人检查的备份就是不存在的备份。

每次重启后,一个脚本检查内核、每个重要的服务和容器、集群的pod、安全流水线,以及最新备份的年龄,并为每一项打印OK或FAIL。它在几分钟内就能捕获“一直工作到重启”这一类问题。同一个脚本后来在例行重启后发现了其他隐藏的故障。

每一个“为了方便”而组可写或全局可写的文件夹都是牺牲品。数据文件夹现在由使用它们的服务拥有,其他任何人——包括我——都没有写权限。

任何重要的东西都在Git里,推送到一个不是我的主文件夹的服务器:脚本、配置、笔记,甚至包括改了什么以及为什么改的记录。

(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →