SleeperGem Borrowed Seven Years of Trust. Four Weeks Later StubMaker Didn't Bother, and Our Ruby Deny-List Was Three Packages Long.
- Patrick Duggan
- 2 minutes ago
- 5 min read
Four weeks ago a RubyGem called Dendreo shipped a malicious version from a maintainer account that had been quiet since October 2020. We wrote about it, because the dormancy was not incidental to the attack — it was the attack. Seven years of accumulated trust, spent all at once. We also ran our own package-reputation scanner against it that morning and published what it said, which was allow.
On August 15, sixteen more malicious gems arrived. This time nobody borrowed any trust at all.
What StubMaker is
OpenSourceMalware — the researcher Paul McCarty, who publishes as 6mile — disclosed the campaign on August 15. The Hacker News picked it up on the 18th. Everything technical below is their finding, not ours; our contribution starts further down, and it starts with an admission.
Sixteen typosquatted RubyGems, published from two accounts with machine-generated handles and human display names: mod8rz41mje, calling itself "Riley Miller," and rbq95bwt6q, calling itself "Alex Davis." Two of the sixteen — brumdler and brundlef — were originally published by a third account, gemlewqqhu1 ("Taylor Moore"), and picked up later through name reclamation.
The payload is a Windows infostealer. It carries a DLL specifically to pull credentials out of Chromium-based browsers, and it collects cryptocurrency wallets, seed phrases, Telegram data, browsing history and stored payment cards. Stolen data goes up to Gofile, and the retrieval links get posted to a host called dresslee.com.
The sixteen names are worth reading aloud, because they tell you what the campaign thinks of you: ubnuler, ubnlder, brumdler, brundlef — all four aiming at bundler, which is in essentially every Ruby project on earth. ri18nr, ise18n, ioe18n, ie18u, iai8n, i1l8n, i18om — seven separate maulings of i18n, a package name that is already a number-and-letter soup and therefore the single easiest thing in the ecosystem to misread. reaker, rakier, orakw for rake. joxn for json. activesupmport for activesupport.
These are not clever. There is no SEO, no homoglyph trickery, no unicode. They are the typos your fingers actually make at eleven at night, industrialised.
The interesting part is what changed in four weeks
Put the two campaigns side by side and they are opposites in the one variable everybody's tooling leans on.
SleeperGem, July 18. Three gems. Two came from real maintainer accounts dormant since 2019 and 2020. The attacker's asset was age — a package with six years of history and a real download record reads as safe to every reputation heuristic ever written, including ours.
StubMaker, August 15. Sixteen gems. Publisher accounts created for the purpose, zero downloads, zero history, names that look like a keyboard fell down the stairs. The attacker's asset was volume and proximity — sixteen shots at the four or five gem names a Ruby developer types most often, betting that one tired install command lands.
Same ecosystem. Four weeks apart. One attack succeeds by having a long history and the other succeeds by having none at all. That is not a scale of sophistication, it is a demonstration that package age is not a safety signal in either direction. It is a lever, and both ends of it are load-bearing for somebody.
If your guardrail rewards old packages, SleeperGem walks through. If it merely flags new ones, StubMaker is indistinguishable from the four thousand legitimately new gems published this month.
Now our part, which is not flattering
We publish a malicious-package deny-list. Anyone can pull it, and an AI coding agent or a CI pre-install hook can check a dependency against it before running the install. It is, as of this morning, 231,426 entries.
Here is how those entries break down by ecosystem.
npm: 219,764. PyPI: 11,655. RubyGems: 3.
Three. And all three of those are the SleeperGem gems, which we added by hand in July after writing about them. Before that batch, the number was zero.
So when the morning sweep surfaced StubMaker today, the honest answer to "are we covered" was: we have never covered this ecosystem at all. A Ruby developer pointing our guardrail at their Gemfile was getting a confident-looking verdict computed against a list that had never contained a Ruby package we did not personally type in.
It gets slightly worse. Our own automated morning brief marked the StubMaker story as AHEAD — already covered — because it matched the word "rubygems" against the SleeperGem post. That is a false AHEAD, and it is the exact inverse of a bug we fixed in July, where the brief kept reporting already-published work as gaps. A match on an ecosystem name proves nothing; it is as generic as matching on "Microsoft." We already demote bare vendor names to a weaker tier for that reason. Ecosystem names now need the same treatment.
What we did about it
All sixteen gem names are now in the feed, as is dresslee.com, attributed to StubMaker, confidence 90 on the packages, verified by read-back rather than by the API saying yes. Our RubyGems coverage went from 3 to 19 — which is better and still nothing to be proud of.
Two deliberate omissions, because the difference matters. Gofile and api.ipify.org are not indicators. They are legitimate services being abused, and putting them in a blocklist would break real workflows for thousands of people to inconvenience one stealer for an afternoon. Same reasoning as July, when SleeperGem's second stage was hosted on a real privacy-collective Git server and we indexed the attacker's account path rather than the domain. We also left the IP behind dresslee.com out of the feed — it is shared hosting, and blocking an address to stop a domain is how you take down somebody's unrelated website.
The structural fix is the one that actually matters, and it is not a list: reputation heuristics have now failed us at both ends of the age axis inside a single month. A scanner that scores a package on how old and popular it is will keep saying allow to the next SleeperGem, and a scanner that only flags novelty will keep drowning in false positives long before StubMaker shows up. What survives both is checking the name against known-bad by name, and checking what the package actually does on install. We are good at the first and we are honest that the second is where the work is.
If you write Ruby
Pull the deny-list and fail your build on a name match — it is free and it takes a pre-install hook. Then go and look at your Gemfile.lock for the five names above that are one keystroke from something you actually use, because bundler, rake, json, i18n and activesupport are in everything, and that is precisely why sixteen gems went hunting for them.
And if you shipped one of these into a Windows dev machine, assume the browser credential store, the wallets and the Telegram session are gone. The DLL was there specifically for the first one.
Primary research: OpenSourceMalware (Paul McCarty / 6mile), disclosed 2026-08-15. Our indicators are a research import of their finding, ingested 2026-08-18 — not a first-party detection, and the timestamps in our feed say so. Confidence capped at 95%, as always.
Every indicator in this post is in the feed. Free.
1.58M+ IOCs, STIX 2.1 / TAXII, 88% novel vs ThreatFox, exploited-CVE leads ahead of CISA. No credit card — a free API key in 30 seconds, and you can audit every claim above against the live endpoints.
Was this useful? Thirty seconds, no cookies, no tracking, no third parties, your address hashed and never stored. If the box below does not load, the same question lives at https://analytics.dugganusa.com/nps.html?post=stubmaker-sixteen-ruby-typosquats-and-a-deny-list-three-packages-long




Comments