OrchidFiles argues the campaign succeeds precisely because the malware never lives in the source — repos compile cleanly while payloads sit in Releases tabs, password-protected zips (with passwords in the README), or Telegram redirects. Static analysis of the repo is useless, which means GitHub's scanners are looking in the wrong place by design.
OrchidFiles emphasizes that the flagged accounts aren't throwaway burners — they have 2-3 year histories, plausible commit graphs on innocuous side projects, and hundreds of stars purchased from the same inflation services legitimate projects use. The novelty isn't malware on GitHub, it's industrial-scale fabrication of developer credibility at ~10,000 repos deep.
The editorial singles out AsyncRAT, XWorm, and Quasar as the payload family developers should fear most, because a RAT on a dev machine becomes a pivot into private repos, cloud credentials, signing keys, and CI runners. LummaStealer-class infostealers are loud and one-shot; persistent remote access turns a single careless download into supply-chain compromise.
A researcher publishing as OrchidFiles spent weeks crawling GitHub for a specific malware signature and surfaced roughly 10,000 repositories distributing trojans. The campaigns aren't subtle phishing attempts pretending to be obscure libraries — they're full-production fakes: game cheats (Valorant, Fortnite, CS2 aimbots), cracked Adobe and JetBrains installers, Discord nitro generators, Roblox executors, crypto trading bots, and a long tail of "dev tools" with slick READMEs, badges, and changelogs.
The payloads cluster into three families. The most common is LummaStealer and its cousins (RedLine, Vidar, Raccoon) — credential stealers that exfiltrate browser cookies, password manager vaults, Discord tokens, Telegram sessions, SSH keys, and crypto wallet files within seconds of execution. The second is crypto clippers: tiny resident processes that watch the clipboard and silently swap any detected wallet address for the attacker's. The third is RATs — AsyncRAT, XWorm, Quasar — for persistent access, which is the one that should worry developers most, because a RAT on a dev machine is a pivot into private repos, cloud credentials, signing keys, and CI runners.
The distribution mechanic is what makes this campaign different: the malware almost never lives in the source. The repos compile cleanly. The binary lives in the Releases tab, or behind a password-protected `Setup.zip` (the password is in the README — a clever way to defeat GitHub's automated scanning), or in a Telegram link the README routes you to. Static analysis of the repo says it's fine. Running the release binary owns you in under a minute.
GitHub has always had malware. What's new is the scale of the social-proof forgery. The flagged accounts aren't day-old throwaways. Many have 2-3 year histories, plausible commit graphs on innocuous side projects, and star counts in the hundreds — bought from the same star-inflation services that legit indie devs occasionally use to bootstrap visibility. The exact signals a senior dev uses to triage a repo at a glance — account age, star count, commit cadence, a README that doesn't read like ChatGPT — are now table stakes for the attackers.
The second shift is the AI agent attack surface. Cursor's agent mode, Cline, Aider, Devin, Claude Code, and the long tail of OSS coding agents will, on instruction, search GitHub, clone a promising-looking repo, and run its quickstart. Some will `pip install` or `npm install` whatever a trending Stack Overflow answer recommends without pinning. None of them are doing meaningful supply-chain analysis. The same researcher noted that several of the trojan repos had been cited by AI chat answers as solutions to specific developer questions — likely because the SEO-optimized READMEs got indexed and ranked.
The third shift is the gaming-to-dev crossover. Most of these repos target gamers, and the prevailing instinct is to wave that off — "not my problem, I don't run aimbots." But credential stealers don't care about your job title. A LummaStealer infection on a kid's laptop that shares a household network with a dev machine still siphons every browser-saved GitHub PAT, npm token, and AWS access key it can find. And the same kit is being repackaged as "open-source dev utilities" — fake CLI tools for Solana, Ethereum, AWS, Kubernetes. The same trojan that looks like a Fortnite cheat on Monday is a `solana-wallet-balance-checker` on Wednesday.
Community reaction on the HN thread (723 points) split predictably. One camp argued GitHub's abuse team is structurally outmatched — 10,000 repos at the bottom of a long tail is below the threshold where a humans-in-the-loop process can keep up, and the automated scanning that catches binaries in-tree is trivially evaded by putting them in Releases. The other camp argued the deeper problem is GitHub as a default trust anchor: developers extend more trust to a github.com URL than they do to a random `.zip` from a forum, and that asymmetry hasn't been earned by GitHub's actual moderation capacity.
Treat any GitHub release binary as untrusted by default — the same way you'd treat an .exe from a Discord DM. A 60-second vetting checklist worth running before you clone, install, or — critically — let your AI agent install on your behalf:
Account age and pattern. Click the maintainer. If the account is under a year old, that's a flag. If it's older but the commit graph shows nothing until a 3-week burst on this one repo, that's the bought-history pattern. Real maintainers have messy histories: dead side projects, forks of friends' stuff, a few stars on weird repos from 2019.
Star velocity vs. issue activity. 800 stars and 2 issues, both closed by the maintainer within an hour of opening, is star-farm signature. Real popular repos have angry users.
The Releases tab. If the README says "download from releases" and the release is a password-protected zip, walk away. The password mechanic exists specifically to defeat scanning.
Source vs. binary alignment. If the repo claims to be a Python tool but the release is a 40MB Windows executable with no build script that produces it from the source — the binary isn't from the source.
Lock your AI agent down. Configure Cursor, Cline, Aider, and Claude Code to refuse to run release binaries or arbitrary install scripts without confirmation. For `npm` and `pip`, force `--ignore-scripts` in your agent's shell profile (yes, this breaks some legitimate packages — that's the cost). Pin every dependency by exact version in agent-generated `requirements.txt` and `package.json`. If your agent framework auto-runs trending packages from search results without these guardrails, that's the framework's fault, not yours, but you eat the consequences either way.
Sandbox the first run. A fresh Docker container, a throwaway VM, or at minimum a non-privileged user with no access to your `~/.aws`, `~/.config/gh`, `~/.ssh`, or browser profile. Five extra minutes to spin up. Zero minutes if you skip it and get hit.
The interesting question isn't whether GitHub takes down these 10,000 repos — they will, slowly, and 10,000 more will replace them by Q4. The interesting question is whether GitHub starts treating release binaries as a distinct trust tier from source, with separate scanning, separate provenance requirements (Sigstore, SLSA attestations), and visible signals in the UI when a release was built from the displayed commit vs. uploaded as an opaque blob. Until then, the burden sits on developers and — increasingly — on the AI agents we're handing the keys to. The trojans got better at looking legitimate faster than our agents got better at being skeptical. That asymmetry is the actual story.
Top 10 dev stories every morning at 8am UTC. AI-curated. Retro terminal HTML email.