13,000 张内部截图出现在公开 GitHub 上,而背后没有任何攻击者

安全研究人员发现,来自 300 多个组织的逾 13,000 张内部截图静静躺在公开的 GitHub 仓库中。这些截图并非被盗。它们是由这些组织正在使用的编程智能体在日常工作中发布出去的。
这一由安全公司 Glow 报告的发现,是近一段时间以来较具启发性的泄露事件之一,因为通常的假设在这里都不成立。没有入侵,没有被窃取的凭据,也没有恶意的内部人员。一个自动化工具做了它被要求做的事,而它被要求做的事中,恰恰包含提交那些本不该离开公司的文件。
一张截图是如何进入公开仓库的
编程智能体截图有合理的理由。当智能体被要求验证某项用户界面改动是否生效时,它会打开浏览器、加载页面、截取图像,并将其与预期结果进行比对。这张图像就是证据。许多智能体会把它保存到工作目录,以便之后复查这一步。
从那里到公开仓库只有几步之遥。如果智能体的工作目录就是项目文件夹,而项目文件夹又是一个 git 仓库,那么写入磁盘的截图距离被提交只差一次 `git add`。如果智能体把提交和推送作为其正常工作流的一部分,且没有任何机制过滤新增文件,那么截图就会流向该仓库指向的任何远程地址。
现在把这种情况在数百个组织、数千次运行中重复数月。没有人决定要发布内部截图。是工具链的默认行为造成了这一切,而这条链路中没有任何一环在做检查。
为什么这不是一个小失误
一张内部截图往往比人们预想的更能暴露信息。它可能显示带有客户名称的仪表盘、含定价信息的管理后台、预发布环境、缺陷跟踪系统,或者屏幕角落的聊天窗口。它可能显示一个尚未发布的产品状态。汇总起来看,来自 300 个组织的 13,000 张图像,就是这些公司当时在做什么的一张地图。
这些图像还会长期留存。推送到公开仓库的提交会留在历史记录中,即便该文件已从当前版本中删除,除非重写历史。因此,这个暴露问题并不会被事后一次清理提交所修复——而这恰恰是大多数团队首先会想到的做法。

为什么智能体会让情况更糟
人类开发者若为拉取请求截图,通常会在附上之前先看一眼。图像就在眼前,由这个人决定它是否可以安全分享。这一瞬间的判断就是过滤器,而且大多数时候都有效。
智能体没有这样的时刻。它以完成任务为优化目标,而保存产物本身就是完成任务的一部分。这个循环中没有任何环节会追问该产物是否敏感,因为循环中没有任何环节具备判断这一点所需的能力。智能体并不是在人类意义上的粗心大意。它只是在严格按指令行事。
这与智能体设计中多个领域反复出现的教训如出一辙。对于手动输入命令的人来说没问题的权限,对一个以机器速度行动、永不疲倦的系统来说就不再没问题。人类每周提交一次截图,是一次疏忽。而智能体在一整批系统中每次运行都这么做,就是一种策略结果。
解决方案长什么样
本可防止此事的控制手段并不稀奇。为截图目录添加一条 `.gitignore` 规则是最简单的做法,但它只有在有人在智能体运行之前写好时才会生效。一个扫描特定路径下图像文件的 pre-commit 钩子,可以补上忽略文件漏掉的部分。为智能体在仓库之外提供一个用于存放临时产物的暂存目录,则能从源头消除问题。
这些做法都不依赖于检测某张图像是否敏感。它们依赖于提前决定智能体的输出可以去往何处。这是一个设计决策,必须由运行智能体的团队来做出,因为智能体自己无法做出这个决定。
为什么数字还在增长
来自 300 个组织的 13,000 张图像这一数字并不是固定值。它是扫描时处于公开状态的仓库的一个快照,随着更多团队采用智能体、更多仓库被推送,这个数字还会上升。研究人员扫描的是公开仓库,这意味着真实总数——包括发生过同样错误的私有仓库——从外部无从得知。
受影响的组织并非都是小公司。该发现点出了 300 多家,涵盖使用同一套智能体工具的初创公司和规模更大的企业。这正是默认行为问题的本质:它不看公司规模,因为每一家使用该工具的公司都继承了同样的默认设置。
报告没有说的事
该发现并未声称任何被暴露的图像曾被恶意使用,也没有证据表明项目之外有人翻看过它们。危害是潜在的,而非已被证实的:这些材料是公开的,任何人都可能看过。而在相关案例中,例如凭据被写入公开文件,危害一旦发生就是即时的。
报告也没有告诉我们,其中有多少图像在任何有意义的意义上属于敏感内容。有些几乎可以肯定只是空白测试页面的截图。但泄露事件是以其中最糟糕的一项来评判的,而不是平均值,而横跨 300 个组织的 13,000 张图像意味着,最糟糕的那一项很可能真的会暴露实质内容。
背后的模式
Glow 的发现只是一批类似报告中的一个。研究人员已经表明,编程智能体会引用并不存在的软件包,攻击者可以通过注册这些名称来加以利用。还有人发现智能体会把凭据或令牌写入不该写入的地方。共同的线索是:智能体在完成工作的过程中会顺带产生各种产物,而每一个产物都是潜在的泄露点。
令人安心的解读是,这是可以修复的,而且多半归结为卫生习惯问题。不那么令人安心的解读是,行业部署智能体的速度,快于其为智能体输出构建防护栏的速度。一家会审计其智能体读了什么的公司,往往并不会审计它们写了什么。
这周该做的事
如果团队正在让编程智能体对仓库进行操作,以下这些即时检查值得一做。看看智能体的工作目录是否在仓库内部,截图或日志是否会落到那里,以及提交环节是否会过滤任何内容。既检查当前目录树,也检查仓库历史,找出那些不应公开的图像文件。并且为智能体指定一个位于目录树之外的暂存路径,用于存放任何临时内容。
这些都不需要新的工具。它需要的是这样一个决定:智能体的输出,和智能体的输入一样,是团队有意控制的东西,而不是出于偶然。