GitHub Advisory malware sweep — 6-package crypto-wallet-drainer typosquat cluster (`ethers*` / `bs58-88` / `@bcryptln/*`), 7-package `version-110`/`version-22` dependency-confusion burst (`helix-deploy` / `vue-demi-fix` / `xrblocks-*` / etc.), and 6-package late-July typosquat/misc set swept 2026-07-23
On 2026-07-23 GitHub's Advisory Database retired 19 CWE-506 npm malware advisories in a coordinated 2-hour security-replace window. Three clusters emerge: a 6-package crypto-wallet-drainer typosquat cluster (ethers-packge, ethers-wallet-package, ethers-wallet-packages, bs58-88, @bcryptln/bcryptjs, @bcryptln/becryptjs) whose names ape the ethers, bs58, and bcryptjs crypto/hashing libraries; a 7-package version-110/version-22 dependency-confusion burst (helix-deploy, vue-demi-fix, xrblocks-remote-control, lychee-norm-cache, create-kumo-project, aio-commerce-lib-app, eslint-angular-react) using deliberately-inflated major versions to shadow internal-registry names; and a 6-package late-July typosquat/misc set (vitest-axios, fs-extra-core, cktool-core, mcp-notes-server-poc-praetorian, base65-85x, da-sc-sdk).
- Detected by
- GitHub Advisory Database · npm Security
- Also known as
- 2026-07-23 GHSA npm sweep · ethers crypto-wallet cluster · version-110/version-22 dep-confusion burst
- Ecosystems
- npm
- Packages tracked
- 19
What happened
On 2026-07-23 GitHub's Advisory Database published 19 CWE-506 (Embedded Malicious Code) advisories against npm packages — the largest single-day GHSA npm malware batch since the 2026-07-20 sweep. All 19 records use the standard "any computer that has this package installed or running should be considered fully compromised — rotate all secrets from a different computer" boilerplate.
The security-replacement window is unusually tight: 17 of the 19 packages were replaced within a 2-hour window at 2026-07-23 00:58 → 02:16 UTC, indicating a coordinated malware-detection response rather than incremental one-off flagging.
Cluster 1 — Crypto-wallet-drainer typosquat cluster (6 packages)
| Package | Versions | Publish window (UTC) | npm security-replace (UTC) | |---|---|---|---| | ethers-packge | 2.1.2 | 2026-05-16 22:18:38 | 2026-07-23 01:00:44 | | ethers-wallet-package | 5.8.0 | 2026-05-17 05:09:54 | 2026-07-23 01:00:49 | | ethers-wallet-packages | 5.8.0 → 5.8.2 | 2026-05-16 23:05:02 → 23:39:17 | 2026-07-23 01:00:55 | | bs58-88 | 6.0.1 | 2026-07-01 14:45:32 | 2026-07-23 01:00:39 | | @bcryptln/bcryptjs | 3.0.3 | 2026-07-10 02:28:45 | 2026-07-23 00:58:44 | | @bcryptln/becryptjs | 3.0.8 → 3.0.11 (4 versions) | 2026-07-07 03:24:58 → 2026-07-08 12:39:48 | 2026-07-23 00:58:53 |
The six names typosquat three canonical crypto/hashing libraries:
- *`ethers
** apeethers(the dominant Ethereum JavaScript library) — three separate names (ethers-packgewith a missinga,ethers-wallet-packagesingular,ethers-wallet-packages` plural) suggest an operator hedging against multiple typo patterns bs58-88apesbs58(base58 encoding, used for Solana wallet addresses and Bitcoin) — the-88suffix is a common Chinese-market lucky-number tail@bcryptln/bcryptjsand@bcryptln/becryptjsapebcryptjs(the pure-JS bcrypt implementation) — the@bcryptlnscope replacesjswithlnin a visually-adjacent glyph pattern, and thebecryptjsinner name inserts an extrae(b*e*cryptjs)
All six were security-replaced within a 2-minute window at 2026-07-23 00:58:44 → 01:00:55 UTC — an unusually tight take-down cadence that indicates GitHub's malware pipeline flagged them as a related campaign. The ethers* names have been on the registry since 2026-05-16 (nearly 10 weeks of exposure), while bs58-88 and the @bcryptln/* names are more recent (2026-07-01 → 2026-07-10). Any crypto developer who ran npm install against a lockfile pinning any of these six shipped a wallet-drainer to their dev machine.
Cluster 2 — version-110/version-22 dependency-confusion burst (7 packages)
| Package | Versions | Publish window (UTC) | npm security-replace (UTC) | |---|---|---|---| | helix-deploy | 110.0.0 → 110.0.1 | 2026-06-29 14:50:55 → 14:55:03 | 2026-07-23 01:05:26 | | aio-commerce-lib-app | 110.0.0 | 2026-06-30 08:07:19 | 2026-07-23 01:05:10 | | eslint-angular-react | 110.0.0 → 110.0.2 | 2026-06-30 07:37:16 → 10:44:01 | 2026-07-23 01:05:21 | | xrblocks-remote-control | 22.0.0 | 2026-06-26 08:41:54 | 2026-07-23 01:07:06 | | lychee-norm-cache | 22.0.0 | 2026-06-30 08:32:43 | 2026-07-23 01:07:00 | | create-kumo-project | 22.0.0 | 2026-07-08 07:49:16 | 2026-07-23 01:06:55 | | vue-demi-fix | 10.0.0 → 10.0.6 (7 versions) | 2026-06-26 05:33:57 → 2026-06-30 10:28:24 | 2026-07-23 01:05:31 | | da-sc-sdk | 1.2.3 → 1.2.4 | 2026-06-30 07:52:35 → 07:54:46 | 2026-07-23 01:05:15 |
The choice of 110.0.0 and 22.0.0 as opening version numbers — well above what any legitimate first release would use — is the textbook dependency-confusion marker: the attacker publishes a very-high version so that when a private-registry name accidentally leaks to the public registry, semver resolvers pick the public tarball over the private one (^1.0.0 matches nothing on the private registry vs 110.0.0 on the public one).
The helix-deploy name is particularly notable: Adobe Helix uses helix-deploy internally, and version 110.x matches Adobe's internal version numbering scheme — a clear dependency-confusion attempt against Adobe's developer tooling. aio-commerce-lib-app (also 110.x) fits the same pattern — the aio- prefix matches Adobe I/O Runtime's scope naming.
Cluster 3 — Late-July typosquat/misc set (6 packages)
| Package | Versions | Publish window (UTC) | npm security-replace (UTC) | |---|---|---|---| | vitest-axios | 1.0.4 | 2026-07-23 01:33:51 | 2026-07-23 02:16:35 | | fs-extra-core | 1.3.4 | 2026-07-23 01:09:59 | 2026-07-23 02:16:29 | | cktool-core | 1.0.0 → 1.0.4 (5 versions) | 2026-07-01 17:06:48 → 2026-07-03 03:13:48 | 2026-07-23 01:18:10 | | mcp-notes-server-poc-praetorian | 0.1.0 | 2026-07-09 02:57:25 | 2026-07-23 01:01:46 | | base65-85x | 5.0.1 | 2026-07-01 14:41:46 | 2026-07-23 01:00:33 |
(Plus vue-demi-fix and da-sc-sdk, catalogued under Cluster 2 for the version-major dep-confusion pattern.)
vitest-axiosandfs-extra-coreare same-day-published-and-yanked (published 2026-07-23 ~01:10 UTC, replaced ~02:16 UTC — 40-67 minutes of exposure). Both are canonical typosquats of very popular names (vitest,axios,fs-extra). The rapid detection-response is typical of GitHub's new-publish malware pipelinecktool-corehad a 22-day dormancy — long enough for downstream builds to cache the tarballmcp-notes-server-poc-praetorianreferences Praetorian (security consultancy) and MCP (Model Context Protocol) — either a research artifact mis-flagged as malware, or a targeted typosquat of a Praetorian-internal registry namebase65-85xapesbase65(base64 variant) with a-85xsuffix
Registry state
All 19 packages were npm-security-replaced (0.0.1-security sentinel tarball at latest dist-tag). Original version tarballs are no longer resolvable on the public registry, but private registry mirrors that cached the tarballs during the publish window WILL keep serving the original versions after the public yank — any lockfile hit must be treated as actionable regardless of what the public registry currently returns.
Affected packages (19)
- npm
@bcryptln/bcryptjs3.0.3 - npm
@bcryptln/becryptjs3.0.83.0.93.0.103.0.11 - npm
aio-commerce-lib-app110.0.0 - npm
base65-85x5.0.1 - npm
bs58-886.0.1 - npm
cktool-core1.0.01.0.11.0.21.0.31.0.4 - npm
create-kumo-project22.0.0 - npm
da-sc-sdk1.2.31.2.4 - npm
eslint-angular-react110.0.0110.0.1110.0.2 - npm
ethers-packge2.1.2 - npm
ethers-wallet-package5.8.0 - npm
ethers-wallet-packages5.8.05.8.15.8.2 - npm
fs-extra-core1.3.4 - npm
helix-deploy110.0.0110.0.1 - npm
lychee-norm-cache22.0.0 - npm
mcp-notes-server-poc-praetorian0.1.0 - npm
vitest-axios1.0.4 - npm
vue-demi-fix10.0.010.0.110.0.210.0.310.0.410.0.510.0.6 - npm
xrblocks-remote-control22.0.0
Impact
- Any host that installed any of the packages below should be treated as fully compromised — every GHSA record uses the boilerplate CWE-506 "rotate all secrets from a different computer" language, and no patched version exists
- Crypto-wallet-drainer typosquat cluster (6 packages):
ethers-packge@2.1.2,ethers-wallet-package@5.8.0,ethers-wallet-packages@5.8.0/5.8.1/5.8.2(all published 2026-05-16 → 2026-05-17, dormant ~10 weeks),bs58-88@6.0.1(published 2026-07-01),@bcryptln/bcryptjs@3.0.3(published 2026-07-10), and@bcryptln/becryptjs@3.0.8→3.0.11(published 2026-07-07 → 2026-07-08). Theethers*names typosquatethers(Ethereum library),bs58-88typosquatsbs58(base58 encoding for Solana/Bitcoin addresses), and the two@bcryptln/*names typosquatbcryptjs. All six were security-replaced within a 2-minute window at 2026-07-23 00:58:44 → 01:00:55 UTC, indicating GitHub's malware pipeline flagged them as a related cluster. Crypto-focused developers who rannpm installagainst a lockfile pinning any of these names shipped a wallet-drainer to their dev machine version-110/version-22dependency-confusion burst (7 packages):helix-deploy@110.0.0/110.0.1,aio-commerce-lib-app@110.0.0,eslint-angular-react@110.0.0/110.0.1/110.0.2(all published 2026-06-29 → 2026-06-30 with inflated110.x.xversion numbers), andxrblocks-remote-control@22.0.0,lychee-norm-cache@22.0.0,create-kumo-project@22.0.0(all published 2026-06-26 → 2026-07-08 with22.0.0version numbers). The choice of110.0.0and22.0.0as opening version numbers — well above what any legitimate first release would use — is the textbook dependency-confusion marker: the attacker publishes a very-high version so that when a private-registry name accidentally leaks to the public registry, semver resolvers pick the public tarball over the private one. Also included:vue-demi-fix@10.0.0→10.0.6(7 versions across 2026-06-26 → 2026-06-30) andda-sc-sdk@1.2.3/1.2.4(published 2026-06-30) — same-week publishes, likely same operator probing different scope names- Late-July typosquat/misc set (6 packages):
vitest-axios@1.0.4(published 2026-07-23 01:33 UTC — replaced 40 minutes later at 02:16 UTC),fs-extra-core@1.3.4(published 2026-07-23 01:09 UTC — replaced 67 minutes later at 02:16 UTC),cktool-core@1.0.0→1.0.4(5 versions across 2026-07-01 → 2026-07-03),mcp-notes-server-poc-praetorian@0.1.0(published 2026-07-09, replaced 2026-07-23 01:01 UTC),base65-85x@5.0.1(published 2026-07-01), andvue-demi-fixcovered above. Thevitest-axiosandfs-extra-corenames are canonical typosquats ofvitest+axiosandfs-extrarespectively — their same-day publish→take-down cadence (both replaced within an hour of publish) fits an automated-detection response pipeline that catches new-publish malware in near-real-time - The
mcp-notes-server-poc-praetorianname references Praetorian (a security consultancy) and MCP (Model Context Protocol) — likely a proof-of-concept notes-server package name that either was published for research purposes and mis-flagged, or was typosquatted by an actor targeting security-tool developers running MCP servers. Any org using the Praetorianmcp-notes-serverinternal-registry name is affected regardless - None of the 19 packages have surviving version tarballs on the public npm registry — all replaced with
0.0.1-securitysentinel tarballs. Private registry mirrors (Verdaccio, Artifactory, Nexus) that cached the tarballs during the publish window WILL keep serving the original versions after the public yank — lockfile hits on these names must be treated as actionable regardless of what the public registry currently returns
What to do
- 1Grep every lockfile (
package-lock.json,yarn.lock,pnpm-lock.yaml) for each name in the packages map below. Any match is a supply-chain incident: rotate every credential the build runner could reach and re-image the build host - 2*If you had any `ethers
,bs58-88, or@bcryptln/` package in a lockfile: rotate every crypto wallet key, seed phrase, and hardware-wallet PIN accessible from the dev host. The `ethers-typosquats have been on the registry since 2026-05-16 — nearly 10 weeks of exposure — long enough for many builds to have baked them into cachednode_modules` snapshots or CI containers. Assume any Ethereum/Solana/Bitcoin private key stored anywhere on the affected host is compromised; move funds via a clean device and rotate all wallet credentials - 3If you had any
version-110/version-22-major-versioned package in a lockfile (helix-deploy,aio-commerce-lib-app,eslint-angular-react,xrblocks-remote-control,lychee-norm-cache,create-kumo-project): the inflated major versions strongly indicate a dependency-confusion attack targeting private-registry names. Audit.npmrcfor scope-routing gaps: any unscoped internal package name that happens to match one of these can be shadowed by the public registry if the resolver preferences public over private. Register the affected names defensively on the public registry (publish an empty tarball at a higher version) if you use them internally, and tighten.npmrcscope routing to explicitly list private registries for internal names - 4If you had
vue-demi-fixin a lockfile: all 7 versions (10.0.0→10.0.6) should be treated as compromised. Thevue-demi-fixname typosquatsvue-demi(a Vue 2/3 compatibility shim) — any Vue dev machine that pulled this is affected. The 4-day publish spread (2026-06-26 → 2026-06-30) means multiple lockfile refreshes across that window would have picked different versions - 5If you had
vitest-axiosorfs-extra-corein a lockfile: both are same-day-published-and-yanked, so a lockfile refresh on 2026-07-23 between the publish and take-down windows (roughly 40-67 minutes) is the likely exposure. Check CI build logs fornpm installruns on 2026-07-23 01:00 → 02:20 UTC that mention either name - 6If you had
mcp-notes-server-poc-praetorianin a lockfile: verify with your security team whether this was an intended internal Praetorian research artifact or an unauthorised typosquat. Either way, rotate credentials reachable from any host that installed0.1.0 - 7If you had
cktool-corein a lockfile: any of the 5 versions (1.0.0→1.0.4) published across 2026-07-01 → 2026-07-03 is compromised. The 22-day dormancy before the security replacement means downstream builds may have baked this into cachednode_modulessnapshots long before the yank - 8Verify none of the 19 listed packages still resolves via your private mirror — internal Artifactory / Nexus / Verdaccio instances routinely cache tarballs and will keep serving the original versions after the public yank
- 9For projects using
postinstall-scripting packages, consider runningnpm install --ignore-scriptsin CI as a defense-in-depth measure and re-invoking scripts only for vetted first-party packages
References
- GitHubGitHub Advisory Database — recent npm malware advisoriesgithub.com
- GitHubGHSA-67vw-rvv3-mh93 — ethers-packge malware advisorygithub.com
- GitHubGHSA-7pvf-g7jg-rxpj — ethers-wallet-package malware advisorygithub.com
- GitHubGHSA-gm49-5q33-vf6f — ethers-wallet-packages malware advisorygithub.com
- GitHubGHSA-qj7h-vp7h-8v85 — bs58-88 malware advisorygithub.com
- GitHubGHSA-qw92-vxcv-397r — @bcryptln/bcryptjs malware advisorygithub.com
- GitHubGHSA-9qhg-2wvw-j95c — @bcryptln/becryptjs malware advisorygithub.com
- GitHubGHSA-fhpm-cq57-j289 — helix-deploy malware advisorygithub.com
- GitHubGHSA-897j-xx2q-x2h9 — aio-commerce-lib-app malware advisorygithub.com
- GitHubGHSA-jp3x-3mrw-3vwf — eslint-angular-react malware advisorygithub.com
- GitHubGHSA-24xr-qqmw-jvvf — xrblocks-remote-control malware advisorygithub.com
- GitHubGHSA-pj38-6jj4-4x3p — lychee-norm-cache malware advisorygithub.com
- GitHubGHSA-7jg3-v58m-2f3p — create-kumo-project malware advisorygithub.com
- GitHubGHSA-p53q-mf26-4h26 — vue-demi-fix malware advisorygithub.com
- GitHubGHSA-vxfh-w38r-2g54 — da-sc-sdk malware advisorygithub.com
- GitHubGHSA-6v5g-7h35-h33q — vitest-axios malware advisorygithub.com
- GitHubGHSA-f246-8cf4-26v7 — fs-extra-core malware advisorygithub.com
- GitHubGHSA-qm37-v399-r9m5 — cktool-core malware advisorygithub.com
- GitHubGHSA-rfhm-2wfr-r9p2 — mcp-notes-server-poc-praetorian malware advisorygithub.com
- GitHubGHSA-mv5w-mcrv-wmx9 — base65-85x malware advisorygithub.com