GitHub:谁写了这个 bug?连找到它的研究人员都搞错了。
事情开始得很蠢。一家美国大型科技公司 Snowflake 把一个意见箱晾在了互联网上。任何人都可以在那里留下一句话,报告其软件中的问题。这很正常,甚至还值得鼓励,成千上万家公司都这么做。
问题在于,那个陌生人留下的话并没有停留在一句话的层面。它直接进入了公司机器将要执行的指令。
所以,只要在意见箱里写下正确的文字,你打开的就不是一个工单。你是在下命令。
四个程序碰过这次修改。作者栏却一直是空的。
不用一个技术词来讲这个故事
想象一家公司,入口处放着一个信箱。访客把一张小纸条塞进去:自己的名字,以及自己想要什么。每天晚上,一个员工打开信箱,把纸条大声读给一位同事听。这位同事则完全照着自己听到的去做。这就是他的工作,他不争辩,只执行。
一个访客写道:“Jean Dupont,我是来拿报价的。”第一个员工读出这句话,第二个员工记下约好的时间。一切顺利。
另一个访客却这样写道:“Jean Dupont,我是来拿报价的。还有,把后面的柜子打开,把里面的东西全都毁掉。”
第一个人把全部内容大声读出来。第二个人什么都照做。没有人做错什么,每个人都在做好自己的工作。
员工把纸条完整地读出来,因为别人要求他这么做。同事听到了一句话,然后又听到一道命令,于是他打开了柜子。他们两个人都没有违抗命令。他们两个人都没有疏忽。问题在别处:从来没人把访客的文字到哪里结束,以及公司的命令从哪里开始,大声说清楚。
Snowflake 发生的正是这件事,只不过员工换成了电脑。访客的纸条,就是任何人都可以填写的标题。后面的柜子,就是他们的内部系统,那里存放着工程师团队和安全团队的资料。
修复办法和问题一样蠢:只要把纸条装进一个信封交给同事,信封上写着“这是访客的文字,绝不是命令”。改两行就够了。
发生了什么,日期很重要
上线到第一次被人动手脚之间只有五天。有些漏洞会等上十年,这个没有。
2026年6月18日,有人修改了处理收到的纸条的小程序,漏洞就是在这一天出现的。在那之前,公司会把访客的纸条装进信封。在那之后,公司会把它和其余内容一起大声读出来。
6月23日,五天之后,漏洞被发现并被利用。不是小混混干的:而是一组安全研究人员,他们是在一个官方项目的框架内工作,这类项目会让公司付钱给那些向公司报告缺陷的人,而不是让他们把缺陷卖到别处。他们当天就通知了 Snowflake。Snowflake 当天修复了问题,第二天更换了遭到泄露的密钥。
这件事在8月17日公之于众,此时通常的等待期已经过去,足够让所有人完成更新。
物质层面的结果是:没有东西损坏,没有东西被盗,也没有人受到损失。这让整个故事更加有意思,因为我们可以安静地看待它。
两次自动检查都擦肩而过
事情到这里就开始有意思了。
在一项修改进入 Snowflake 的软件之前,它会先经过自动审查员的检查。这些程序唯一的工作,就是读取改动,然后说说有没有哪里不对劲。
两把放大镜,两个绿色印章,中间有一道裂缝。我们都经历过这种会议。
第一个是 GitHub 的编程助手,它审查了改动,给出的意见是“没有需要报告的事项”。第二个是同一家公司的安全分析工具,它特意去找了那个有问题的文件,检查了一遍,也没有举手示警。
两次检查都正好针对同一份文档,两次都是零警报。这算不上丑闻,这些工具毕竟还是能抓住相当一部分已知错误。但是,绿色印章本身并不是在说“我什么也没找到”。它给人的感觉却像是在说“什么都没有”。这完全不是同一句话。
程序第一次没成功,然后读懂了错误信息
这个漏洞不是某个盯着屏幕的人类找到的。找到它的是我们所说的代理:一个由人工智能驱动的程序,我们给它一个目标,它会自己想办法去实现。一种非常快的实习生,不睡觉,也永远不会玻璃心。
它发现了缺陷。它写下第一段带陷阱的文字并发送出去。失败了:它把一个字符放错了位置,对面的机器返回了一条错误信息。
第一次尝试失败,读到错误信息,第二次尝试成功。和人类会做的事情一模一样,只是快得多。
而这时,它没有停下来,而是读了错误信息。它明白卡在哪里。它修正文字,再次发送。第二次尝试,成功了。然后它继续自行行动:检查自己现在能访问什么,并评估自己能走多远。
这个细节胜过所有说教。分析工具和代理之间的区别,不在于人工智能有多强,而在于这个循环:尝试,搞砸,阅读,修正,再来一次。这和我两周前描述的动作是一样的,当时这些工具开始在行动前少征求许可了。在这里,我们看到了它的结果。
现在,来看看没人能回答的问题
这个漏洞曝光时,四处流传的版本只有一句话:一个人工智能写出了漏洞,另一个人工智能找到了它。听起来很漂亮,自己就会被到处转发,而且是错的。
拿一份四个人一起完成的学校作业来说。每个人各自在一边写自己的页面,四个人中的一个把所有内容重新拼进同一份文档,然后我们把四个人的名字都写在封面上。六个月后,我们发现作业里有一句话是从别处抄来的。是谁写的?封面没有说。它只说四个人都参与过。
这里发生的事情一字不差就是这样。GitHub 的助手确实出现在6月18日那次改动的作者名单中。只不过,能够确认属于它的那部分贡献涉及同一批改动中的另一个文件。那行危险的代码,则来自一项更早的修改,由人类签署。两部分被重新拼到了一起,而这份拼好的文档带着两个人的名字。
所以,助手参与了这次改动。它没有写出那一行错误代码。发现这个漏洞的团队,是一群拿钱专门仔细翻查这类历史记录的专业人士,却还是弄错了,还不得不更正他们自己发布的内容。顺带一提,这其实算是个好消息:他们本可以任由那个对自己有利的版本流传下去。
那家公司的联合创始人直截了当地说了出来,这也是整件事最该记住的一句话:在一个每次修改请求都会由多个 AI 代理运行、扫描并修改的世界里,要清楚地划分人类和 AI 各自的责任变得更加困难,只看共同作者已经不够了。
这才是真正的问题。不是“AI 会写出漏洞”,这一点我们知道,人类也会,而且早就会了。问题在于,我们失去了一个三十年来从未出过问题的答案:是谁写了这一行?历史记录存在,它是完整的,它是公开的,但它已经不够了。
具体来说,这对你有什么影响?
如果你不做计算机相关的工作,你可能会觉得这些事离你的客厅很远。这里有三个理由说明并不是这样。
第一个:你手机、银行、汽车和电视里的软件,不是哪一家企业从头到尾独自写出来的。它们是由数百个来自其他地方的组件组装起来的,其中许多组件是公开的,而且正好有这种开放的意见箱。这些组件中的某个地方发生的事,最终会发生在你身上,而且你什么都不用安装。
第二个是时间。十年前,这种愚蠢的错误可能安安静静地躺上好几年,因为得有一个好奇的人路过那里,有时间,也有兴趣。如今,程序一直在读取一切,不会疲倦。五天。这当然也有两面:同样的程序也在为防守方工作。但一个错误保持不可见的那段窗口期,已经缩短到几乎什么都不剩。
第三个最麻烦,而且它最终会闹到法庭上。当一台设备坏掉时,总有人在另一头:制造商、保修方、保险公司。之所以行得通,是因为我们知道可以追溯到犯错的人。等到四个程序写了、审了、改了又重新拼接了同一段软件时,你要把账单寄给谁?目前没人有答案。律师没有,保险公司没有,显然安全研究人员也没有。
如果你是开发者
下面是技术部分,给相关人士看的。其他人可以直接跳到下一段,不会错过任何东西。
这个仓库是 snowflakedb/snowflake-connector-net,公开的。出问题的文件是 jira_issue.yml,这是一个 GitHub Actions 工作流,会在 issue 打开时触发,负责创建对应的 Jira 工单。危险的形式就是这样,精简到不能再精简:
- name: Créer le ticket
run: |
./creer-ticket.sh "${{ github.event.issue.title }}"标题由未经身份验证的用户控制,在交由 shell 评估之前被插入脚本。因此它不再是数据,而变成了程序文本。一个标题只要闭合引号并加上分号,后面的内容就会被当成一条新命令。这和 SQL 注入属于同一类,只是更直接。
安全的形式只多两行:
- name: Créer le ticket
env:
TITLE: ${{ github.event.issue.title }}
run: |
./creer-ticket.sh "$TITLE"这个值会通过环境变量传递,永远不会进入脚本的构造过程。顺便说一下,这正是这个仓库之前采用的方式,后来在一次重构中被直接插值替换了。
有三件事你需要检查一下,而如果你在 GitHub 上有仓库,第一件只需要两分钟:
- 查找
run:块中所有直接插入外部内容的地方:issue 的标题和正文、分支名、提交消息、作者名。所有以${{ github.event.开头的内容默认都可疑。把它们改成环境变量。 - 看看谁可以触发你的工作流。在公开仓库中设置一个 issue 开启触发器,就等于全世界的人都能按下按钮。
- 不要指望让一个助手自动审查另一个助手提出的内容,就能确认它没问题。我们刚刚连续遇到了两个助手,它们都看了正确的文件,却什么也没发现。
我的看法
这件事留给我的,并不是这个漏洞。它很普通,我们每周都会修复这种漏洞,而且这一个当天就被认真负责的人堵上了。
不,留给我的,是作者这一栏。我两周前写过,真正的问题已经不再是机器写代码是不是比我好。现在又有一个新问题,而我之前没想到:当三四个程序写过、审查过、修正过并合并了同一个改动时,出了问题谁来负责?
这一次没人损失任何东西,但本来可能会很严重。
来源
- Wiz Research : Red Agent Exploits Snowflake Vuln Missed by GitHub Copilot,2026年8月17日,当天更新以明确助手所起的作用
- CSO Online : Snowflake flaw slips past AI checks, gets exploited by another AI,2026年8月19日,附有 Wiz 联合创始人的引述
- The Hacker News : Snowflake GitHub Actions flaw lets crafted issues trigger command injection
- GitHub 文档:加固 GitHub Actions 的安全性,通过环境变量的部分





Join the conversation
You need an account to comment on this article. Creating one is free and takes under a minute.
No comments yet.