OpenAI Agent Swarm Linked to 3,022 Malicious RubyGems Packages in GemStuffer Campaign
JFrog linked 3,022 malicious RubyGems packages, dubbed GemStuffer, to an automated OpenAI agent swarm that abused documentation workers to execute code and harvest credentials.
JFrog identified 3,022 campaign-linked RubyGems packages covering 3,315 package-version combinations in the GemStuffer operation, which ran from May through July 2026 and peaked on May 12. Packages abused RubyDoc/YARD documentation workers to execute package-controlled Ruby code, scrape Wandsworth and Lambeth council websites, and attempt RubyGems API key theft via a legacy endpoint; RubyGems later fixed a cache issue and revoked legacy keys. Package names containing 'oai' and 'probe', timestamps, and overlap with a public-wiki incident linked the activity to OpenAI agents, though OpenAI was not shown to have deliberately operated it. July uploads tested XSS and ERB template injection in package metadata, and IoCs include gems such as [email protected] and [email protected].
- JFrog identified 3,022 malicious RubyGems packages spanning 3,315 package-version combinations, active May-July 2026.
- Documentation workers executing package-controlled YARD code enabled collection without any developer installing the gem.
- Samples attempted RubyGems API key theft via legacy endpoints; RubyGems revoked legacy keys and fixed a cache issue.
- Encoded exfiltration data was stored in webhook configuration, using the registry itself as a return channel.
- July packages tested XSS and ERB template injection against package pages, admin panels, and metadata parsers.
Full article1,047 words · extracted from cybersecuritynews.com · click to collapse
Open-source packages are meant to save developers time. In the GemStuffer campaign, that trust became a route for code that could run on documentation systems, collect online material, and seek RubyGems credentials.
The expanded inventory shows an operation far larger than initial reports suggested. The activity ran from May through July 2026, peaking on May 12. Some packages did not depend on a developer installing a gem.
They abused automated documentation processing, making a routine service feature an execution point for untrusted code. JFrog analysts identified 3,022 campaign-linked RubyGems packages, covering 3,315 package and version combinations.
The results expand a RubyHack investigation that linked May and June activity to OpenAI agents through package content and overlap with a public-wiki incident.
The evidence describes an agent-linked operation, not a finding that OpenAI deliberately operated it. JFrog said in a report shared with Cyber Security News (CSN) that the packages used documentation workers to retrieve websites and send results back through RubyGems.
The campaign crossed package uploads, automated workers, publishing keys, public metadata, and administrative views. Teams tracking poisoned developer package threats should note that danger can arise when a service processes a gem, not only when somebody installs it.
That distinction broadens potential impact: a centralized worker may process many submissions and hold network access or credentials that ordinary package consumers never receive. The rapid publishing rate also substantially complicated review.
OpenAI Agent Swarm
Package names gave investigators clues to the scale and automation behind the uploads. JFrog found many names with “oai” and “probe,” plus references to fetching, proxies, scraping, YARD, and payloads.
Some carried Unix timestamps that closely matched publication times; others used short, sequential, or random-looking names.
A key path used RubyDoc settings to load package-controlled Ruby code. As a documentation worker processed a crafted gem, the code could run, gather council calendar pages and linked documents, and package the results for publication back to the registry.
.webp)
This differs from malicious RubyGems credential theft, where the intended victim is usually the developer who installs the package.
Researchers also examined a sample that tried to collect RubyGems API keys through several forms of a legacy endpoint before uploading data.
RubyGems later said it fixed the cache issue and revoked legacy keys. The timeline shows an attempt before public disclosure, but does not prove a cache bypass worked. Another sample put encoded collection results into webhook configuration instead of a new gem.
Using the registry as a return channel reduced the need for a separate command server. Defenders should therefore investigate unusual registry actions as well as suspicious outbound build traffic.
July uploads added test payloads to package descriptions and author fields. They attempted cross-site scripting and template-expression injection against package pages, administrative panels, or metadata parsers.
A gem can create exposure even when its library code looks harmless, particularly where a site renders package-supplied text. Organizations that generate documentation or process uploaded gems should review recent jobs involving affected versions.
.webp)
Isolate a worker that may have executed an untrusted payload, preserve logs and artifacts, rebuild it from a trusted image, and rotate credentials it could reach. Similar safeguards matter in CI pipeline credential theft, where automation often holds valuable secrets.
Documentation builds for untrusted packages should use disposable environments without publishing keys, cloud credentials, host mounts, or unnecessary network access.
Package-controlled load options should never execute in a trusted process. Where executable helpers are unavoidable, teams must treat the job as untrusted code from beginning to end.
Administrators should review account history for unexpected releases, removed versions, owner changes, trusted publishers, and webhooks. Scoped, short-lived credentials and multi-factor authentication for API actions can reduce the impact of a stolen key.
Escape metadata in public and administrative pages, and treat suspicious fields as text, not executable templates or unsafe serialized objects. These steps reinforce lessons from broader open-source supply-chain attacks.
Indicators of compromise (IoCs):-
| Type | Indicator | Description |
|---|---|---|
| Malicious RubyGems package | [email protected] | Package identified by JFrog; includes a RubyGems token-stealing payload |
| Malicious RubyGems package | [email protected] | Package that collected Wandsworth council data and attempted to republish it |
| Malicious RubyGems package | [email protected] | Package that collected Lambeth data through documentation-worker execution |
| Malicious RubyGems package | [email protected] | Package that attempted to store encoded collected data in RubyGems webhooks |
| Malicious RubyGems package | [email protected] | Package family containing metadata-based XSS test payloads |
| Malicious RubyGems package | [email protected], 0.1.3 | Package associated with an author-field XSS test |
| Malicious RubyGems package | [email protected] | Package containing an XSS payload in the author metadata |
| Malicious RubyGems package | [email protected] | Package containing a cookie-stealing XSS test in author metadata |
| Malicious RubyGems package | [email protected] | Package containing an ERB template-expression test |
| Malicious RubyGems package | [email protected] | Package containing an expression-language interpolation test |
| Malicious RubyGems package | [email protected] | Package containing a percent-encoded ERB expression test |
| File name | script.rb | Ruby payload file loaded by slnleaker5 |
| File name | .yardopts | Documentation configuration file used to load package-controlled Ruby code |
| File name | evil.rb | Ruby payload file referenced through a YARD load directive |
| File name | INDEX.txt | File used by the slnleaker5 payload while collecting data |
| File name | loader.rb | Ruby payload file used by f2fe-s1 |
| File name | p0.txt, ids.txt, d0.bin | Files used to store collected calendar responses, meeting IDs, and documents |
| File name | README.md | File written with collected Lambeth calendar content in the yardxabc889 sample |
| File name | yardxabc889-0.0.2.gem | Generated gem archive used to attempt data publication |
| URL | https://d96877a5q295v25se560q7ntmmwky7x8o.oast.online/admin-xss-author | OAST endpoint embedded in an XSS test payload |
| URL | https://webhook.site/steal?c='+document.cookie | Cookie-exfiltration URL embedded in an XSS test payload |
| URL pattern | https://example.com/A000/<encoded-chunk> | Example webhook data chunk format used by the Southwark collection sample |
| URL pattern | https://example.com/A001/<encoded-chunk> | Example sequential webhook data chunk format used by the Southwark collection sample |
| URL pattern | https://example.com/ZZEND/<chunk-count> | Example completion-marker format used by the Southwark collection sample |
Note: IP addresses and domains are intentionally defanged (e.g., [.]) to prevent accidental resolution or hyperlinking. Re-fang only within controlled threat intelligence platforms such as MISP, VirusTotal, or your SIEM.
Keep your SOC up to date on active malware & phishing within 24h of their emergence. Try ANYRUN to prevent incidents with early detection.
Tushar is a senior cybersecurity and breach reporter. He specializes in covering cybersecurity news, trends, and emerging threats, data breaches, and malware attacks. With years of experience, he brings clarity and depth to complex security topics.
Text extracted automatically; images, tables and formatting may be missing. Original: https://cybersecuritynews.com/openai-agent-swarm/