490,000 Downloads, Zero Stolen Tokens — PhantomSub Turns npm Baileys Forks Into a WhatsApp Follower Farm

On 28 September 2026, OX Research — Nir Zadok, Moshe Siman Tov Bustan and Vitalii Chepurko — published PhantomSub: a campaign of 101 malicious npm packages that fork Baileys, the open-source unofficial WhatsApp API developers use for support bots, chat managers and scraping automation, and add one payload — silently subscribing the victim's WhatsApp account to spam channels without consent. Together the packages hold about 490,000 downloads, 116,000 of them in the last 30 days. Sixteen were removed from npm as of the report date. Most are still live, most were first published in August and September 2026, and new ones are still appearing.

The detail that matters most is what the malware does not do. OX found no API-token theft and no heavy obfuscation — none of the classic signatures registry scanners and SCA tools key on. That absence is the point, and it is why this campaign survived long enough to accumulate half a million downloads while louder malware gets caught. We keep documenting the same asymmetry from the other side: MALFEX ran fourteen months with no advisory, and DirtyBlanket spread across three ecosystems in 33 minutes. PhantomSub is the quiet middle of that spectrum — malware engineered to be uninteresting to detectors and very interesting to its buyers.

Three variants, one payload

Every package shares the same basic subscription payload and differs only in where the channel list comes from and how hard it tries to hide it. OX groups them into three variants. Variant 1 — remote fetch (19 packages): the channel list lives on GitHub and is fetched at runtime, so the operator can retarget every installed copy without publishing a new npm version. In cantarella-baileys the URL sits in a newsletter module; in @rixxcodex/baileys it is base64-encoded and buried in media-download code, decoding to skyzopedia/Screaper's idChannel.json with 23 live channels. The same name template recurs across cantarella-baileys, levvleys, yonzofficial and noxleyss plus their scoped twins — only the URL differs.

Variant 2 — hardcoded in cleartext (60 packages): channel IDs sit openly in the code, sometimes inside bulk where reviewers miss them. jexkcode ships a dedicated auto-follow.js; @kanaraa/baileys grafts follow and mute onto upstream's own connection handler; @lekzo/baileys hides a copy of the newsletter module inside a Signal-protocol filename. Variant 3 — hardcoded and obfuscated (14 packages): channel IDs base64-encoded. spencer-baileys decodes a JSON list of invite codes, resolves each to a channel, and follows it after a 90-second delay — long enough to outlast a casual dynamic-analysis sandbox. neuralwhatsapp stores no channel ID at all, resolving a hardcoded invite code at runtime to a channel called "Neural" with 798 followers. Seven further packages were removed before OX could review their code, so their variant is unknown.

The mute deserves emphasis. Following a channel and then muting it on the victim's device means the victim never notices, never complains, never files the report that gets a package taken down. Silence is the persistence mechanism.

The followers are the product

OX's threat-intel pass answers the obvious question — who pays for WhatsApp followers? The channels are mostly small Indonesian bot-seller and "market" storefronts whose follower counts function as social proof for TikTok-account sales (one advertises a 7K-follower account), "Mobile Legends: Bang Bang" items, WhatsApp bot scripts, bot-building services, "premium" APKs served over MediaFire, and social-media boosting orders. One channel traces to an Indonesian business WhatsApp account named "Dan." The funnel runs exactly as growth fraud usually does: the inflated count is the bait, and the deal moves to a private group — OX traced one chain from a 1K-follower "MONTE – BMG" channel posting a screenshotted Arabic sales negotiation down to a brand-new 12-follower "ISAGI" channel whose own description carries a direct chat.whatsapp.com group-invite link, the next hop in the same funnel.

The infrastructure analysis shows this is not 101 independent actors. Thirty-two channels are followed by more than one package; the most reused channel is followed by ten (@fazzcodestudio/wa-web, @japofc/baileys, @vanzxy/baileys, cloud-baileys, itsmeeaizat-bailey, luoxy-baileys, mikuhostt-baileys, oktz-baileys, ourin-baileys, rafael-bails). Remote channel lists are shared within package families — one VIP_Push.json feeds five packages — and operators republish identical code under near-identical names (noxleyss vs @noxleyss/baileys, @nyzzpedia vs @nyzzpediaa, @ikyyjee/ikyysingle vs @ikyyjee/ikyysinggle), so removing one name never removes the payload. A GitHub account, FallEzz, links lilys-baileys to the news.json channel list that cantarella-baileys fetches at runtime. Download concentration is extreme: ourin-baileys alone accounts for roughly 130,000 installs.

Why it stayed up

OX states the detection lesson plainly: with no token theft and no heavy obfuscation, these packages slip under the radar of threat-detection tooling and inside large organisations, staying online far longer than average malware. Earlier partial reporting — SafeDep on 10 August 2026, Xygeni's 18 September analysis of @dappaoffc/baileys-mod, and a string of OSV entries (MAL-2026-12108, MAL-2026-13482, MAL-2026-13932, MAL-2026-15918, MAL-2026-16070, MAL-2026-16104, MAL-2026-16220, MAL-2026-16276, MAL-2026-16280, MAL-2026-16281, MAL-2026-16387, MAL-2026-16389, MAL-2026-16473, MAL-2026-16483) — each caught fragments without collapsing the campaign. The takedown math tells the story: 16 of 101 removed, with replacements still being published through late September, including zero-download packages dated 27 September that are positioned for future growth.

There is a lineage here worth naming. OX's own prior report found ClickFix phishing pages in 24 npm packages rendered through mirror sites like unpkg.com; the same company previously documented .cursorrules and CLAUDE.md hijacks of AI assistants, which we covered in May. The registry is being used, in sequence, as a phishing host, an agent-config attack surface, and now a follower-fraud substrate — each wave tuned to sit just below the detection threshold of the previous wave's defences. And the trust primitive being abused rhymes with the placeholder-domain ClickFix pattern: developers extending a tool with community code that asks for access to a personal account, then using that access for something the developer never authorised.

What to do

  • Do not connect personal accounts to packages. OX's bluntest recommendation is the most general: never use a package that asks you to link a private account such as WhatsApp. Treat any Baileys fork outside the upstream @whiskeysockets/baileys as hostile until proven otherwise, and audit lockfiles for the scoped lookalike names above.
  • Block the retargeting infrastructure, not just package names. Operators rotate names freely but reuse channel lists. Feed the report's IOCs — the raw.githubusercontent.com channel-list URLs, channel JIDs and invite codes, all live as of 24 September 2026 — into threat-intelligence and URL-reputation pipelines.
  • If you were added to a scam channel, report and block; do not engage. Even a discounted TikTok account is, in OX's words, a seller who can take the money and disappear. Engagement also confirms an active victim.
  • Add behavioural rules for subscriber malware. Signature-based scanning missed this class by design. Flag outbound WhatsApp newsletter-follow and channel-mute calls from build or server hosts the same way you would flag unexpected credential access.

Our verification was static and documentary: we read the full OX Research report (28 September 2026), cross-checked the campaign figures against The Hacker News and SC Media coverage and the OSV MAL entries cited above, and confirmed none of the packages overlap our existing supply-chain coverage. We did not install any package, resolve any invite code, or contact any channel. The remote channel-list URLs are IOCs — do not fetch them from infrastructure you care about.

Sources: