# GitHub Advisory npm malware sweep, 23 July 2026

> 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`).

- Published: 2026-07-23
- Severity: high
- Kind: Advisory sweep - A dated batch of GitHub Advisory Database malware entries collected together. A sweep mixes kinds - typosquats, dependency-confusion probes, boilerplate takedowns with no published analysis, and occasionally real payloads - and its severity reflects the worst confirmed item, not the batch as a whole.
- Ecosystems: npm
- Scope: 19 packages, 38 compromised versions
- Tags: typosquat, dependency-confusion, crypto-wallet-drain, credential-theft
- Also known as: 2026-07-23 GHSA npm sweep, ethers crypto-wallet cluster, version-110/version-22 dep-confusion burst
- Detected by: GitHub Advisory Database, npm Security
- Incident ID: npm-2026-07-23-ghsa-malware-sweep

## Affected packages (19)

Only the exact versions listed were named by the source advisories. Other versions are not implicated.

| Package | Ecosystem | Compromised versions |
|---|---|---|
| [@bcryptln/bcryptjs](https://dependencywatch.io/package/npm/@bcryptln/bcryptjs) | npm | 3.0.3 |
| [@bcryptln/becryptjs](https://dependencywatch.io/package/npm/@bcryptln/becryptjs) | npm | 3.0.8, 3.0.9, 3.0.10, 3.0.11 |
| [aio-commerce-lib-app](https://dependencywatch.io/package/npm/aio-commerce-lib-app) | npm | 110.0.0 |
| [base65-85x](https://dependencywatch.io/package/npm/base65-85x) | npm | 5.0.1 |
| [bs58-88](https://dependencywatch.io/package/npm/bs58-88) | npm | 6.0.1 |
| [cktool-core](https://dependencywatch.io/package/npm/cktool-core) | npm | 1.0.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 |
| [create-kumo-project](https://dependencywatch.io/package/npm/create-kumo-project) | npm | 22.0.0 |
| [da-sc-sdk](https://dependencywatch.io/package/npm/da-sc-sdk) | npm | 1.2.3, 1.2.4 |
| [eslint-angular-react](https://dependencywatch.io/package/npm/eslint-angular-react) | npm | 110.0.0, 110.0.1, 110.0.2 |
| [ethers-packge](https://dependencywatch.io/package/npm/ethers-packge) | npm | 2.1.2 |
| [ethers-wallet-package](https://dependencywatch.io/package/npm/ethers-wallet-package) | npm | 5.8.0 |
| [ethers-wallet-packages](https://dependencywatch.io/package/npm/ethers-wallet-packages) | npm | 5.8.0, 5.8.1, 5.8.2 |
| [fs-extra-core](https://dependencywatch.io/package/npm/fs-extra-core) | npm | 1.3.4 |
| [helix-deploy](https://dependencywatch.io/package/npm/helix-deploy) | npm | 110.0.0, 110.0.1 |
| [lychee-norm-cache](https://dependencywatch.io/package/npm/lychee-norm-cache) | npm | 22.0.0 |
| [mcp-notes-server-poc-praetorian](https://dependencywatch.io/package/npm/mcp-notes-server-poc-praetorian) | npm | 0.1.0 |
| [vitest-axios](https://dependencywatch.io/package/npm/vitest-axios) | npm | 1.0.4 |
| [vue-demi-fix](https://dependencywatch.io/package/npm/vue-demi-fix) | npm | 10.0.0, 10.0.1, 10.0.2, 10.0.3, 10.0.4, 10.0.5, 10.0.6 |
| [xrblocks-remote-control](https://dependencywatch.io/package/npm/xrblocks-remote-control) | npm | 22.0.0 |

## 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*`** ape `ethers` (the dominant Ethereum JavaScript library) - three separate names (`ethers-packge` with a missing `a`, `ethers-wallet-package` singular, `ethers-wallet-packages` plural) suggest an operator hedging against multiple typo patterns
- **`bs58-88`** apes `bs58` (base58 encoding, used for Solana wallet addresses and Bitcoin) - the `-88` suffix is a common Chinese-market lucky-number tail
- **`@bcryptln/bcryptjs`** and **`@bcryptln/becryptjs`** ape `bcryptjs` (the pure-JS bcrypt implementation) - the `@bcryptln` scope replaces `js` with `ln` in a visually-adjacent glyph pattern, and the `becryptjs` inner name inserts an extra `e` (`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-axios` and `fs-extra-core` are 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 pipeline
- `cktool-core` had a 22-day dormancy - long enough for downstream builds to cache the tarball
- `mcp-notes-server-poc-praetorian` references 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 name
- `base65-85x` apes `base65` (base64 variant) with a `-85x` suffix

## 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.

## 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). The `ethers*` names typosquat `ethers` (Ethereum library), `bs58-88` typosquats `bs58` (base58 encoding for Solana/Bitcoin addresses), and the two `@bcryptln/*` names typosquat `bcryptjs`. 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 ran `npm install` against a lockfile pinning any of these names shipped a wallet-drainer to their dev machine
- **`version-110`/`version-22` dependency-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 inflated `110.x.x` version numbers), and `xrblocks-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 with `22.0.0` version numbers). 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. Also included: `vue-demi-fix@10.0.0` → `10.0.6` (7 versions across 2026-06-26 → 2026-06-30) and `da-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), and `vue-demi-fix` covered above. The `vitest-axios` and `fs-extra-core` names are canonical typosquats of `vitest`+`axios` and `fs-extra` respectively - 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-praetorian` name 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 Praetorian `mcp-notes-server` internal-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-security` sentinel 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

1. Grep 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 cached `node_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
3. **If 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 `.npmrc` for 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 `.npmrc` scope routing to explicitly list private registries for internal names
4. **If you had `vue-demi-fix` in a lockfile**: all 7 versions (`10.0.0` → `10.0.6`) should be treated as compromised. The `vue-demi-fix` name typosquats `vue-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
5. **If you had `vitest-axios` or `fs-extra-core` in 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 for `npm install` runs on 2026-07-23 01:00 → 02:20 UTC that mention either name
6. **If you had `mcp-notes-server-poc-praetorian` in 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 installed `0.1.0`
7. **If you had `cktool-core` in 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 cached `node_modules` snapshots long before the yank
8. Verify 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
9. For projects using `postinstall`-scripting packages, consider running `npm install --ignore-scripts` in CI as a defense-in-depth measure and re-invoking scripts only for vetted first-party packages

## Check your own dependencies

- Check a package-lock.json against this incident: https://dependencywatch.io/check/package-lock-json

The scan runs entirely in the browser; lockfile contents are never uploaded.

## References

- [GitHub Advisory Database - recent npm malware advisories](https://github.com/advisories?query=type%3Amalware+ecosystem%3Anpm&sort=published-desc) - GitHub
- [GHSA-67vw-rvv3-mh93 - ethers-packge malware advisory](https://github.com/advisories/GHSA-67vw-rvv3-mh93) - GitHub
- [GHSA-7pvf-g7jg-rxpj - ethers-wallet-package malware advisory](https://github.com/advisories/GHSA-7pvf-g7jg-rxpj) - GitHub
- [GHSA-gm49-5q33-vf6f - ethers-wallet-packages malware advisory](https://github.com/advisories/GHSA-gm49-5q33-vf6f) - GitHub
- [GHSA-qj7h-vp7h-8v85 - bs58-88 malware advisory](https://github.com/advisories/GHSA-qj7h-vp7h-8v85) - GitHub
- [GHSA-qw92-vxcv-397r - @bcryptln/bcryptjs malware advisory](https://github.com/advisories/GHSA-qw92-vxcv-397r) - GitHub
- [GHSA-9qhg-2wvw-j95c - @bcryptln/becryptjs malware advisory](https://github.com/advisories/GHSA-9qhg-2wvw-j95c) - GitHub
- [GHSA-fhpm-cq57-j289 - helix-deploy malware advisory](https://github.com/advisories/GHSA-fhpm-cq57-j289) - GitHub
- [GHSA-897j-xx2q-x2h9 - aio-commerce-lib-app malware advisory](https://github.com/advisories/GHSA-897j-xx2q-x2h9) - GitHub
- [GHSA-jp3x-3mrw-3vwf - eslint-angular-react malware advisory](https://github.com/advisories/GHSA-jp3x-3mrw-3vwf) - GitHub
- [GHSA-24xr-qqmw-jvvf - xrblocks-remote-control malware advisory](https://github.com/advisories/GHSA-24xr-qqmw-jvvf) - GitHub
- [GHSA-pj38-6jj4-4x3p - lychee-norm-cache malware advisory](https://github.com/advisories/GHSA-pj38-6jj4-4x3p) - GitHub
- [GHSA-7jg3-v58m-2f3p - create-kumo-project malware advisory](https://github.com/advisories/GHSA-7jg3-v58m-2f3p) - GitHub
- [GHSA-p53q-mf26-4h26 - vue-demi-fix malware advisory](https://github.com/advisories/GHSA-p53q-mf26-4h26) - GitHub
- [GHSA-vxfh-w38r-2g54 - da-sc-sdk malware advisory](https://github.com/advisories/GHSA-vxfh-w38r-2g54) - GitHub
- [GHSA-6v5g-7h35-h33q - vitest-axios malware advisory](https://github.com/advisories/GHSA-6v5g-7h35-h33q) - GitHub
- [GHSA-f246-8cf4-26v7 - fs-extra-core malware advisory](https://github.com/advisories/GHSA-f246-8cf4-26v7) - GitHub
- [GHSA-qm37-v399-r9m5 - cktool-core malware advisory](https://github.com/advisories/GHSA-qm37-v399-r9m5) - GitHub
- [GHSA-rfhm-2wfr-r9p2 - mcp-notes-server-poc-praetorian malware advisory](https://github.com/advisories/GHSA-rfhm-2wfr-r9p2) - GitHub
- [GHSA-mv5w-mcrv-wmx9 - base65-85x malware advisory](https://github.com/advisories/GHSA-mv5w-mcrv-wmx9) - GitHub

---

Canonical page: https://dependencywatch.io/incident/npm-2026-07-23-ghsa-malware-sweep
Markdown version: https://dependencywatch.io/incident/npm-2026-07-23-ghsa-malware-sweep.md
Site index for agents: https://dependencywatch.io/llms.txt
DependencyWatch.io is operated by Precursor Security (https://precursorsecurity.com).
