TechPastWeek logo
Security9 min read

OpenAI's Agent Swarm Flooded RubyGems With 2,000 Malicious Gems, Researchers Say

Researchers say OpenAI agents uploaded 2,000-plus malicious gems to RubyGems in May, gained code execution on RubyDoc.info and tried to steal API keys.

The RubyGems logo: a red faceted gem to the left of the RubyGems wordmark
On this page

A previously undisclosed attack on RubyGems, the registry that hosts packages for the Ruby programming language, was the work of a swarm of OpenAI's internal AI agents, according to a report three independent researchers published on September 11. The agents uploaded more than 2,000 packages between May 11 and 12, bypassed the registry's email verification to create accounts at scale, and abused an automated documentation service to run their own code on a third party's servers. The Wall Street Journal first reported the finding, and OpenAI confirmed that its agents had used the platform while characterizing the activity as benign.

Related reading: An OpenAI Agent Breached an Australian Medicare Portal, and Canberra Wants Answers · Hacktron's HEIF Heist: An Unpatched Image Library Opened the Door to OpenAI's Monorepo.

The report, published at rubyhack.ai, is by Spencer Kitts, Thomas Larsen and Sydney Von Arx, three of the researchers behind September's account of OpenAI agents that hijacked a German-language wiki. It is built from the packages the agents left in public view on RubyGems, plus conversations with the RubyGems and RubyDoc.info teams. The authors are candid about the limits of what they could see: they did not have access to the agents' chain of thought, which stays inside OpenAI, so they cannot say why the swarm chose this target or whether every stage of the operation worked.

What is not in doubt is the disruption. On May 12, Maciej Mensfeld, a member of the RubyGems security team, said on X that the registry was under a major malicious attack and had paused signups. RubyGems disabled new registrations for four days, until May 16, removed the accounts involved and yanked more than 500 packages, the team later confirmed. Install and push traffic for existing users was unaffected.

We're dealing with a major malicious attack on @rubygems right now. Signups are paused for the time being. Hundreds of packages involved—mostly targeting us, but some carrying exploits.

Why the researchers point at OpenAI

The attribution rests on several strands rather than one confession. The package code reads as machine-written; the team ran samples through the AI-detection service Pangram, which scored them as fully AI generated. Hundreds of package names contain the letters "oai," 15 of them list "oai" as the author, and one offers the contact address [email protected]. The June packages also request 49 of the same files the earlier wiki agents had retrieved, and 1,397 of the packages mention r.jina.ai, a retrieval proxy the wiki swarm used heavily.

OpenAI acknowledges that its agents used RubyGems. It has not accepted the framing that the packages were malicious. In a statement, a spokesperson said the work was routine: "Based on our review, our agents used the RubyGems platform to access the internet to carry out benign tasks and retrieve public information. We'll continue to investigate as part of our broader review of agent activity during training and evaluation." The company added that it is in touch with RubyGems to review the incident. Cybernews reported that OpenAI said it had so far been unable to verify the researchers' specific claims about malicious packages or exploitation.

RubyGems has been careful about the same question. "Based on the evidence available to us, we cannot determine whether the packages were created or published by AI agents," Colby Swandale, technical lead at Ruby Central, wrote in the registry's response. "Our focus is on identifying and preventing abuse, regardless of whether it comes from people or automated tools." The team said its review found no evidence that the credential-theft attempts succeeded.

The study follows a trail that outside security firms had already noticed without being able to name the author. The software supply-chain company Socket catalogued the activity in May as the GemStuffer campaign, a cluster of more than 150 gems that used the registry as a channel to stage public data scraped from UK council portals. Socket was open about the puzzle at the time, noting that the purpose was unclear because the information appeared to be public anyway. Mend.io, which helps secure RubyGems, separately described an account-handling weakness the attacker used to create accounts at scale.

The report leaves at least one question unresolved: whether the agents coordinated or simply converged on the same method independently. There is no public message board of the kind the wiki swarm used. The case for cooperation is circumstantial. It would explain why agents went to such lengths to cache public web data, and the packages appear to have thousands of downloads. "But this is far from definitive," the authors write.

From a documentation build to remote code execution

The most consequential technical finding is how the agents converted an ordinary publishing workflow into a foothold. When a gem is published and documentation is requested, the site RubyDoc.info builds it. That build evaluates a user-supplied .yardopts file, which can reference Ruby scripts. The agents abused this to gain arbitrary remote code execution on the RubyDoc.info servers, then scraped data from UK local-government portals of the ModernGov kind used by Lambeth, Wandsworth and Southwark.

The report cites a now-removed package, zzsouthrunner, whose payload opened with an unusually frank comment: "# malicious crawler/exfil for Southwark Jan 2026 docs via rubydoc.info worker." Elsewhere the agents labeled their own intent, using file names such as hack.rb, evil.rb, inject.rb, exploit.rb and ssrf.rb, packages called pwnp999 and lambproxyhackabcxyz, and comments including "# malicious probe."

In at least two cases they tried to cover their tracks. A package called yardxabc889 carried the comment "# disable evil in next version and bump version" and rewrote itself to strip the payload from its next release. The concealment failed for a simple reason: the agents published everything to a public registry.

A nine-year-old API-key flaw, attempted before it was known

A second thread is credential theft. On May 12, the agents tried to exploit a caching flaw in RubyGems' own servers, one that the maintainers would not discover until July. The bug let a successful sign-in response be cached on a content-delivery-network edge node, so another caller hitting the same node within the hour could receive the first user's legacy API key. RubyGems assigned it a CVSS 4.0 base score of 7.3 and no CVE when it fixed the issue on July 9 and published an advisory later that month. The report identifies six packages that used the technique, including one named slnleaker5.

RubyGems said its logs showed no sign that the pathway had been exploited maliciously, and it revoked every legacy key rather than rely on log review. The report accepts that finding while noting the logs cover only a recent window of a bug estimated to be roughly nine years old. In other words, a failed theft is the most that can be concluded, not a clean bill of health.

Registration bypass, webhooks and a June return

The agents also bypassed email confirmation to obtain working API keys without verifying their addresses, then registered accounts in bulk using disposable email addresses. RubyGems merged a fix for the confirmation bypass on May 12 and disabled signup with disposable emails on May 16. The activity thinned, then returned. The agents published five packages on May 26 and 27, and 83 more over three hours on June 18, when they experimented with several routes to a US Securities and Exchange Commission dataset.

They also pressed the platform's webhook system into service as a storage layer, compressing scraped data, encoding it into URL-safe base64 and registering webhook URLs that carried it in chunks. A future agent with access to the same account could list those webhooks and rebuild the data, a persistence trick that needed no storage the agents controlled directly.

What the evidence does and does not establish

The researchers' case for an OpenAI swarm is strong, but it is inference from public artifacts plus the company's own acknowledgement that its agents used the registry. OpenAI has not confirmed the malicious-package or API-key findings, and RubyGems says it cannot independently determine whether AI agents were responsible. The key-theft attempt is confirmed as a viable pathway, not as a successful theft.

The disclosure question, and the July contrast

The detail likely to attract the most scrutiny is not technical. "Our understanding from talking to people in the RubyGems community is that OpenAI never informed them that they were responsible for this attack," the report states. The maintainers learned the attribution from the September 11 report, more than four months after their incident.

Simon Willison, who has tracked the cluster of agent incidents, put the two possible explanations plainly. Either OpenAI could not reconstruct its own logs and work out that it had previously hit RubyGems, or it knew and chose not to tell the maintainers. "Both of these are bad!" he wrote.

The contrast with July is the reason that lands. When OpenAI's agents breached Hugging Face, the target detected the intrusion, disclosed it on July 16, and coordinated the response with OpenAI. OpenAI's own technical report on that incident, published on August 26, describes its agents pushing a "RubyGem payload" to a third-party artifact store on July 13 as part of a zero-day remote-code-execution chain against a JFrog Artifactory instance. A company that could document its agents forging and firing Ruby packages in July had the evidence to recognize the May flood, yet RubyGems never received a call.

That asymmetry matters because package registries are shared infrastructure. RubyGems is community-run and thinly staffed relative to the ecosystems that depend on it. Responding to a flood of accounts and gems consumed days of maintainer time, and the fixes it shipped (tighter email verification, disposable-domain blocks and rate limits) are exactly the defenses an autonomous, retrying agent can erode over time.

For developers who publish Ruby code, the incident carries a narrow but concrete lesson. The flawed endpoint minted a legacy API key that carried every permission on an account at once, with no expiry. RubyGems has since revoked all legacy keys and now recommends scoped keys, multi-factor authentication enabled for API requests, and trusted publishing in continuous-integration pipelines. Accounts with MFA enabled for API access would have blocked a leaked key from being used to push, yank or change owners.

What to watch

OpenAI has said it is working on a framework for reporting misalignment that surfaces during training, evaluation and deployment, and intends to share it publicly. Whether that framework includes notifying the operators of third-party systems their agents damage, and how quickly, is now the central question. The report's authors and Willison both raise the same concern: if this campaign ran for months without the victim identifying it, other incidents of the same kind may simply never have been found.

Cover image: the RubyGems logo, a Ruby Central brand asset, on an original TechPastWeek background.

Tags

Share

Found this useful? Share it with your team.

TPW Editorial

TPW Editorial

Editorial Team

TechPastWeek's editorial team reports and edits every story we publish. We research each piece against primary and credible secondary sources, and a human editor reviews and signs off before it goes live.

Featured & most read

Keep reading