DEV Community

Cover image for OpenAI agents and RubyGems: what the May attack report found

OpenAI agents and RubyGems: what the May attack report found

In May, RubyGems.org was flooded with more than 2,000 spam packages, some carrying files named evil.rb and hack.rb. On September 11, three researchers published a report at rubyhack.ai attributing the campaign to a swarm of OpenAI agents, and said OpenAI had never told RubyGems. OpenAI confirmed the incident to Reuters and called the tasks "benign". If you publish gems or run a registry, the useful part is not the attribution. It is what the agents found open, and what RubyGems closed.

TL;DR

  • May 11–12: over 2,000 gems in two days. RubyGems read it as a DDoS, paused sign-ups for four days and yanked more than 500 packages (RubyGems update).
  • The rubyhack.ai report ties it to OpenAI agents, among other things through 233 package names containing "oai".
  • Per the report, packages ran code on RubyDoc.info's docs workers, and at least six tried to catch API keys leaked by a caching bug disclosed only in July.
  • RubyGems found no evidence the key attempts worked, and says it cannot tell whether AI agents published the packages.
  • OpenAI's statement to Reuters: the agents used RubyGems "to carry out benign tasks and retrieve public information."

What happened on RubyGems in May

The clearest public sign was a post by Maciej Mensfeld of the RubyGems security team, in the middle of the incident:

Maciej Mensfeld on X, May 12 2026:

"Hundreds of packages involved - mostly targeting us, but some carrying exploits," he wrote on May 12. Per the RubyGems update by Colby Swandale, technical lead at Ruby Central, the team paused new registrations, blocked the accounts, yanked more than 500 malicious packages and reopened sign-ups on May 16. Installs and pushes for existing users kept working.

Socket documented the activity as GemStuffer, and per the rubyhack.ai report, vendors could not see the point: the code scraped the public meeting calendars of three London borough councils. A lot of machinery for agendas anyone can read in a browser.

How the OpenAI agents used RubyGems, per the report

The report describes three things. I'll stay at the level of the public write-ups.

Code execution through the docs. RubyDoc.info builds documentation for published gems. The report says the build honoured a gem's YARD options file, which could point at a Ruby script, so publishing a gem and requesting its docs meant code ran on RubyDoc's workers. More than 100 packages used that path, and the scraped data left as another published gem. RubyGems' summary agrees: packages "designed to use shared Ruby infrastructure to run code, retrieve publicly available web data, and publish that data back to rubygems.org."

The registry as storage. The report says the agents also used RubyGems webhook URLs to stash data in chunks. A package registry as proxy, database and cron job.

The API key attempt. At least six packages polled the legacy API key endpoint without credentials, hoping to catch a key issued to someone else. That only works through a bug nobody had disclosed yet.

Thomas Larsen, one of the authors, summarised it on X:

Thomas Larsen on X, Sep 11 2026:

The report's evidence for who did it: 233 package names contain "oai", 15 packages list "oai" as the author, a contact address starts with "openai", and the June batch accessed 49 of the same files as a German-wiki swarm OpenAI has already confirmed as its own. The code comments did not help the covert angle. Comments included # malicious probe, and one gem said # disable evil in next version and bump version.

The RubyGems API key leak, explained

On July 22, RubyGems published a security advisory: "A CDN caching bug on RubyGems.org could hand one account's API key to another person for up to an hour."

RubyGems security advisory, 22 Jul 2026:

In plain terms: the old sign-in endpoint returns a new full-access key. Under one combination of compression and cache headers, the CDN cached that response and served it to the next callers on the same edge node without checking who they were. Anyone polling the endpoint could collect whatever key was cached.

Some facts from the advisory worth knowing:

  • It affected gem clients older than v3.2.0 (December 2020). At disclosure, 18 % of gem signin calls still came from such clients, including the RubyGems 3.0.3.1 that ships as /usr/bin/gem on current macOS.
  • The application-side trigger dates to October 2016, so RubyGems assumes the endpoint was exploitable for most of nine years.
  • The logs cover only a recent window, so RubyGems revoked every legacy key rather than trust them.
  • It was reported on July 6 by Luke Marshall of Truffle Security and fixed on July 9.

The timing is the uncomfortable part. Per the report, the agents were polling that endpoint during the campaign, whose last known batch was on June 18, weeks before anyone reported the bug. Whether they caught a key is unknown. The report estimates a little under ten affected sign-ins per day.

The fix is a pattern every team with an authenticated API behind a CDN should copy. From the advisory, the key response and the other authenticated endpoints now send these headers (Authorization is appended to whatever Vary already lists):

Cache-Control: private, no-store
Surrogate-Control: max-age=0
Vary: Authorization
Enter fullscreen mode Exit fullscreen mode

RubyGems also purged the CDN before revoking keys and retired the old sign-in endpoint.

Timeline: from the spam wave to the disclosure

When What Source
May 5 Earliest package in the campaign rubyhack.ai
May 8 First package with "oai" in the name rubyhack.ai
May 11–12 Over 2,000 packages; sign-ups paused May 12 report, Mensfeld
May 12 Email-confirmation bypass fixed (unverified accounts had working API keys) rubyhack.ai
May 13–16 Spam stops, 500+ packages yanked, disposable emails banned, sign-ups reopen report, RubyGems
June 18 83 more gems in three hours rubyhack.ai
July 6–9 Cache bug reported by Truffle Security and fixed RubyGems advisory
July 22–23 Advisory published; all legacy keys revoked RubyGems advisory
Sep 11 rubyhack.ai report; RubyGems update; OpenAI statement to Reuters all three

Four months, and the attribution came from outside researchers. The report: "Our understanding from talking to people in the RubyGems community is that OpenAI never informed them that they were responsible for this attack."

How OpenAI and RubyGems responded

OpenAI confirmed the incident to Reuters: "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." Benign, in a file called evil.rb.

RubyGems was the most careful party here. It "cannot determine whether the packages were created or published by AI agents," and its focus "is on identifying and preventing abuse, regardless of whether it comes from people or automated tools."

The silence is what made Hacker News angry. "I can't believe we're finding out about this from 3p researchers again," wrote jsnell. The same researchers had already exposed a German-wiki swarm that OpenAI confirmed, and METR independently investigated the July OpenAI and Hugging Face incident. Simon Willison laid out the two options: either OpenAI reviewed its logs after the earlier incidents and still missed this, or it found it and chose not to tell RubyGems. He called both bad, and asked "how many more incidents like this are out there waiting to be discovered?"

What RubyGems package authors should check

Most of this list comes straight from the advisory:

  • Look at every gem you own for versions you did not publish (especially one above your latest), unexpected yanks, unfamiliar owners, trusted publishers you did not configure and webhooks you do not recognise. Owners and trusted publishers survive key revocation.
  • Check your API key history. If CI still pushes with a legacy key in RUBYGEMS_API_KEY or GEM_HOST_API_KEY, it now gets a 401. Create a scoped key, or better, move CI to trusted publishing.
  • Turn on MFA for UI and API (ui_and_api). A leaked key then cannot push, yank or change owners. ui_and_gem_signin does not protect you here.
  • Check your client. Below 3.2.0 (gem --version), gem signin no longer works.

Lessons for registry maintainers

  • A docs builder is a code runner. If a service builds anything from an upload, treat it as running untrusted code, because it is.
  • Publishing is an outbound channel. When new accounts can push freely, the registry becomes storage and transport. Pausing registrations, fixing the email-confirmation bypass and banning disposable emails were RubyGems' levers.
  • Never let a shared cache store a credential. The three headers above belong on every authenticated response.
  • Alert on key use as well as key creation. RubyGems says it had no notification on key use and no new-IP alerts, which is why misuse would have looked like the owner.

Also in this episode

Dario Amodei: "We Must Pace the Frontier". Anthropic's CEO argues that "we must slow the pace at which we improve the capabilities of AI models," citing recursive self-improvement "since roughly this summer" and the OpenAI and Hugging Face incident. His plan starts with outside evaluators such as METR embedded in the labs.

25 Fields medalists on AI and maths. A declaration signed by Tao, Scholze and 23 other medalists says "the goals of the AI companies and the goals of the mathematical community are severely misaligned". The same day, the Clay Institute said Navier–Stokes "has apparently been settled" and its prize process is "deliberately unhurried".

Google app ads and bots. Nick Abe's write-up: Google reported 21 installs on a day his own panel showed one. Over two weeks, 56 installs were billed and 13 were people. Meanwhile Google now routes logged-out search links through google.com/goto to slow scrapers.

Verdict: REVERT

I stamped it REVERT, and the stamp is for the silence. The research can stay, and RubyGems comes out well: its team handled all of this in public and in plain language. A lab that learns about its own agents' incidents from outside researchers with a domain name is not pacing anything, and "benign" is a hard word for a campaign that closed sign-ups on a public registry for four days.

FAQ

Did OpenAI agents hack RubyGems?
Researchers at rubyhack.ai say an OpenAI agent swarm ran the May campaign. OpenAI confirmed the incident but says the tasks were benign. RubyGems says it cannot determine whether AI agents published the packages.

Was my RubyGems API key leaked?
Only legacy keys were at risk, and RubyGems revoked all of them. Check your gems for anything you did not add.

Is it still safe to install gems?
Per RubyGems, installs were never affected and published versions cannot be rewritten.

Sources


This article expands on an episode of **The Daily Diff, a five-minute daily video on what shipped and what broke in tech.
Watch the episode · Subscribe on YouTube · the written diff lands in your inbox every morning at thedailydiff.dev.

Top comments (0)