Security1 publisher2 min readPublished
Thirteen npm packages ship a stripped-down stealer that uploads Chrome's extension storage wholesale
OpenSourceMalware says WeaselBiscuit borrows functions from DPRK's BeaverTail and OtterCookie but strips out the persistence and the wallet drainer. It runs from memory on an npm import and takes Chrome's extension storage.
The Watch · Security desk
What happened
- OpenSourceMalware documented a previously undocumented JavaScript stealer it calls WeaselBiscuit, delivered by a cluster of 13 npm packages.
- An npm import runs loader.js, which fetches the payload from an Npoint dead drop and executes it directly in memory.
- Once running, it resolves its C2 configuration from a second Npoint URL, profiles the host, and harvests Chrome extension storage on Windows, macOS and Linux.
Compiled by The WatchSomething wrong?How this is made
Why it matters
- exposure Anything a Chrome extension wrote to disk on a machine that ran one of these imports is recoverable by the operator, wallet-extension state included, and reissuing it means per-extension credentials rather than a password reset.
- decision There is no persistence to remove and no drainer to chase, so the response work is deciding which extension-held secrets on build hosts and developer laptops get reissued.
- contradiction OpenSourceMalware lays out Npoint dead drops, ipify and ip-api chaining, OtterCookie-like C2 and numeric campaign IDs, then declines to attribute. Detection keyed to named DPRK clusters is looking in the wrong place.
- precedent WeaselBiscuit is the second recombination of BeaverTail and OtterCookie found in npm since Cisco Talos flagged node-nvm-ssh in October 2025, so the split between those two families keeps getting less useful for triage.
Local Extension Settings is a raw LevelDB key/value store, and WeaselBiscuit uploads every readable, nonempty file under it [12]. Paul McCarty, the researcher who documented the family, said the "Chrome extension-storage capability is financially relevant: it can expose wallet-extension state or other extension-held sensitive data" [11]. The malware has no wallet-draining code of its own, no remote access, no persistence, and it does not pull a second-stage payload such as InvisibleFerret [7].
Eight of the thirteen package names sit under one npm scope, @biz44, and five are unscoped [21]. Six of the scoped names embed a number: id10, id12, id44, id79, id95, id99 [4]. Those are the same six values WeaselBiscuit uses as a numerical campaign ID to tag each install, a scheme OpenSourceMalware says mirrors PolinRider [17][22]. The name id79-client appears twice in the cluster, once under the scope and once bare [23].
Jenn Gile, co-founder of OpenSourceMalware, said it is "a stripped down stealer that borrows several functions from DPRK's BeaverTail and OtterCookie, but is much smaller and self-contained" [5]. The name follows from the sizing. "Hence the 'WeaselBiscuit' name, because a weasel is smaller than an otter, and we can argue that biscuits are less fancy than cookies," Gile said [6]. On attribution the group stops at overlap. It lists the Npoint.io dead drops that NVISO tied to Contagious Interview in November 2025 [14], the nested public-IP and geolocation lookups through api.ipify.org and ip-api.com [15], and C2 architecture that overlaps OtterCookie [16]. It also says operator infrastructure, victimology, campaign metadata and signing material do not conclusively point to North Korea [13].
BeaverTail has been in use since at least late 2022 against software developers, IT professionals and cryptocurrency users [18]. OtterCookie pairs information stealing with remote command execution and was first publicly documented by NTT Security Holdings in December 2024 [19]. In October 2025 Cisco Talos flagged an npm package, node-nvm-ssh, that "had characteristics of BeaverTail and of OtterCookie, blurring the distinction between the two" [20].
Clipboard logging and keystroke capture run on Windows only, and only when the operator at 103.170.217.184:8787 sends the command, so a collection session involves someone typing [10]. The report does not put a number on downloads or victims [24]. The loader executes the payload in memory and the malware does not persist, so the process ends with the build that imported it [8][7], and the extension-held secrets it read stay valid until they are reissued.
What to watch
- Whether npm removes the 13 names and whether the same loader.js and Npoint dead drop reappear under a scope other than @biz44.
- Hard infrastructure or signing evidence that would move WeaselBiscuit from functional overlap to a DPRK attribution.
- A later build that adds persistence, remote access or wallet-draining code back in.