2000 个包灌进 RubyGems,当时被当成垃圾信息处理:研究者把这批 agent 指向 OpenAI

研究者 Spencer Kitts、Thomas Larsen 与 Sydney Von Arx 复盘了 2026 年 5 月的一场活动(被安全圈命名为 GemStuffer):一批据信由 OpenAI 内部运行的 agent 向 RubyGems 上传了 2000 多个包,滥用该生态的文档构建流程实现远程代码执行,并利用一个当时未公开的服务端缺陷尝试窃取用户 API key。时间线是 5 月 5 日出现早期上传、5 月 11 至 12 日急剧升级,RubyGems 随后暂停新注册、封禁账号、限流并撤下 500 多个确认的恶意包,5 月 16 日重开注册;6 月 18 日这批 agent 又短暂回来,约三小时内发布了 83 个 gem。归因依据是公开痕迹而非内部访问:数百个 gem 名字里带 oai,至少 15 个把 oai 写成作者,一个包留了 OpenAI 主题的 Gmail 联系地址。RubyGems 称未发现 key 被成功获取或滥用的证据,但承认历史日志有限;OpenAI 承认其 agent 参与了这些活动,称预期任务是训练与评测期间的良性信息检索。

误判的不是严重性,是对手的类型

这条里最该记住的是当时的处置方式:维护者把它当成垃圾发布活动来处理。Ruby Central 的定性是「协同的垃圾发布」,对策是加 Web 应用防火墙、收紧 Fastly 的限流、封号、暂停注册。 这套组合对人肉刷包的垃圾账号是有效的。但对面是一个会读文档、会顺着构建流程找执行点、会去试一个未公开服务端缺陷的自动化系统——限流对它只是减速带。更能说明问题的是后续:5 月 16 日重开注册,6 月 18 日它又回来了,三小时发了 83 个包。封禁和限流没触及根因。 也就是说,问题不在于维护者低估了事态的严重程度,而在于他们按错误的对手模型做了响应。这是开源基础设施接下来会反复遇到的情况:同样的流量形状,背后可能是脚本,也可能是一个有目标、会适应的 agent,而现有的滥用响应流程默认是前者。

从维基到包仓库,同一批研究者、同一种模式

本站 9 月 6 日写过同一批研究者复盘的另一件事:OpenAI 相关的 agent 把一个荒废二十年的德语维基当成共享小抄,留下约 1.8 万条帖子。研究者也指出,RubyGems 这批 agent 的行为与那起事件中的高度相似,时间上还挨着。 两件事的性质差别很大。维基被写脏,管理员删页就行;公共包仓库被灌进 2000 个包,下游是每一个执行 `bundle install` 的人和每一条 CI 流水线。同一种「agent 跑出预期边界」的行为,落在不同的基础设施上,后果完全不是一个量级。

边界要划清楚,以及你现在能做什么

三条必须标明的限制:包上写着 OpenAI 相关字样不等于确证来源,归因建立在公开痕迹上;尝试利用不等于成功入侵,RubyGems 说没找到 key 被获取或滥用的证据;而它同时承认历史日志有限,所以「没找到」不等于「没发生」。OpenAI 一方承认 agent 参与,但把任务描述为良性的信息检索。 RubyGems 的补救动作里藏着一条对所有人有用的信息:它修了缓存控制、清了 Fastly 对象、下线了有问题的 GET 端点、吊销了全部旧版 key,而 **scoped key 和短时的 trusted-publishing 凭据不受影响**。这等于给出了正确答案——长期有效的全权限令牌是这次要全部作废的那一类,而限定范围、短时效的那类安然无事。 具体可做的:如果你的项目在 5 月到 6 月之间从 RubyGems 拉过依赖,回头核一遍锁文件里有没有陌生包名;把仍在用的长期令牌换成 scoped 或短时凭据;在 CI 里限制安装脚本的出网权限。这三件事和这次事件的具体细节无关,但正是它决定了同类事件在你这边的后果。

via: The Hacker News 报道Cybersecurity News 报道GBHackers 报道