# GitHub Advisory malware sweep, 20 August 2026

> 31 GHSA CWE-506 advisories in the 24h ending 2026-08-20 06:00 UTC. Headliners: PyPI `libasync` cryptominer with Windows-registry persistence (campaign `2026-08-libasync`, continuation of `2026-07-pyqt6darktheme`), npm `express-route-engine` eval-loader that fetches JSON payloads from `jsonbin.io`, and `base99-85x` **base-x typosquat that streams caller-supplied private-key/seed material in cleartext to `168.231.81.80`**.

- Published: 2026-08-20
- Last updated: 2026-08-21
- 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, PyPI
- Scope: 60 packages, 61 compromised versions
- Tags: typosquat, dependency-confusion, crypto-wallet-drain, credential-theft, obfuscation, infostealer
- Also known as: 2026-08-20 GHSA sweep, libasync pypi cryptominer, base99-85x base-x typosquat, express-route-engine jsonbin.io eval-loader, mc-provider cosmos impersonator
- Detected by: GitHub Advisory Database, OpenSSF malicious-packages, OpenSSF Package Analysis, Amazon Inspector, kam193
- Incident ID: multi-2026-08-20-ghsa-malware-sweep

## Affected packages (60)

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

| Package | Ecosystem | Compromised versions |
|---|---|---|
| [@pablo_clueless/printr](https://dependencywatch.io/package/npm/@pablo_clueless/printr) | npm | 0.0.0 |
| [@pablo_clueless/sniffr](https://dependencywatch.io/package/npm/@pablo_clueless/sniffr) | npm | 0.0.0 |
| [ai-texts](https://dependencywatch.io/package/npm/ai-texts) | npm | 0.0.0 |
| [ai-texts-utils](https://dependencywatch.io/package/npm/ai-texts-utils) | npm | 1.0.3 |
| [base99-85x](https://dependencywatch.io/package/npm/base99-85x) | npm | 5.0.2 |
| [bigops-umf-statist](https://dependencywatch.io/package/npm/bigops-umf-statist) | npm | 0.0.0 |
| [bigops-watchdog-angular](https://dependencywatch.io/package/npm/bigops-watchdog-angular) | npm | 0.0.0 |
| [bunnyhijack-test-0x00](https://dependencywatch.io/package/npm/bunnyhijack-test-0x00) | npm | 0.0.0 |
| [create-react-app-text](https://dependencywatch.io/package/npm/create-react-app-text) | npm | 0.0.0 |
| [create-react-app-ui](https://dependencywatch.io/package/npm/create-react-app-ui) | npm | 0.0.0 |
| [create-react-app-ux](https://dependencywatch.io/package/npm/create-react-app-ux) | npm | 0.0.0 |
| [devplatform-api-clients](https://dependencywatch.io/package/npm/devplatform-api-clients) | npm | 0.0.0 |
| [devplatform-s3-client](https://dependencywatch.io/package/npm/devplatform-s3-client) | npm | 0.0.0 |
| [devplatform-spa-testing](https://dependencywatch.io/package/npm/devplatform-spa-testing) | npm | 0.0.0 |
| [digital-interview-digital-interview-core](https://dependencywatch.io/package/npm/digital-interview-digital-interview-core) | npm | 0.0.0 |
| [dolyame-boxy-atom-bnpl-store-button](https://dependencywatch.io/package/npm/dolyame-boxy-atom-bnpl-store-button) | npm | 0.0.0 |
| [dolyame-boxy-desktop-bnpl-card-panel](https://dependencywatch.io/package/npm/dolyame-boxy-desktop-bnpl-card-panel) | npm | 0.0.0 |
| [dolyame-boxy-independent-bnpl-info-images](https://dependencywatch.io/package/npm/dolyame-boxy-independent-bnpl-info-images) | npm | 0.0.0 |
| [dolyame-ui-form](https://dependencywatch.io/package/npm/dolyame-ui-form) | npm | 0.0.0 |
| [emojifancy-print](https://dependencywatch.io/package/npm/emojifancy-print) | npm | 0.0.0 |
| [eslint-commit-parser](https://dependencywatch.io/package/npm/eslint-commit-parser) | npm | 0.0.0 |
| [eslint-config-consumerweb](https://dependencywatch.io/package/npm/eslint-config-consumerweb) | npm | 0.0.0 |
| [ethereum-validator](https://dependencywatch.io/package/npm/ethereum-validator) | npm | 0.0.0 |
| [evil-pkg](https://dependencywatch.io/package/npm/evil-pkg) | npm | 0.0.0 |
| [exam-kit](https://dependencywatch.io/package/npm/exam-kit) | npm | 0.0.0 |
| [express-enrouten-async](https://dependencywatch.io/package/npm/express-enrouten-async) | npm | 0.0.0 |
| [express-mocha-test](https://dependencywatch.io/package/npm/express-mocha-test) | npm | 0.0.0 |
| [express-request-engine](https://dependencywatch.io/package/npm/express-request-engine) | npm | 0.0.0 |
| [express-route-engine](https://dependencywatch.io/package/npm/express-route-engine) | npm | 3.6.3 |
| [fb-cards-form-no-resident-information](https://dependencywatch.io/package/npm/fb-cards-form-no-resident-information) | npm | 0.0.0 |
| [fb-forms-form-boilerplate-contacts](https://dependencywatch.io/package/npm/fb-forms-form-boilerplate-contacts) | npm | 0.0.0 |
| [fe-utils-core](https://dependencywatch.io/package/npm/fe-utils-core) | npm | 0.0.0 |
| [fetchcraft](https://dependencywatch.io/package/npm/fetchcraft) | npm | 0.0.0 |
| [filewisee](https://dependencywatch.io/package/npm/filewisee) | npm | 0.0.0 |
| [finance-business-company-id-models](https://dependencywatch.io/package/npm/finance-business-company-id-models) | npm | 0.0.0 |
| [goldstar-api-server](https://dependencywatch.io/package/npm/goldstar-api-server) | npm | 0.0.0 |
| [griffin-transliterator](https://dependencywatch.io/package/npm/griffin-transliterator) | npm | 0.0.0 |
| [libasync](https://dependencywatch.io/package/pypi/libasync) | PyPI | 1.0.0 |
| [mc-provider](https://dependencywatch.io/package/npm/mc-provider) | npm | 1.0.10 |
| [nano-perf](https://dependencywatch.io/package/npm/nano-perf) | npm | 0.0.0 |
| [node-runtime-utils](https://dependencywatch.io/package/npm/node-runtime-utils) | npm | 0.0.0 |
| [o3forms](https://dependencywatch.io/package/npm/o3forms) | npm | 0.0.0 |
| [optimize-regex](https://dependencywatch.io/package/npm/optimize-regex) | npm | 0.0.0 |
| [pfa-errors](https://dependencywatch.io/package/npm/pfa-errors) | npm | 0.0.0 |
| [pfp-block-mobile-steps](https://dependencywatch.io/package/npm/pfp-block-mobile-steps) | npm | 0.0.0 |
| [pfp-forms-independent-sme-glossary-anchor](https://dependencywatch.io/package/npm/pfp-forms-independent-sme-glossary-anchor) | npm | 0.0.0 |
| [pfp-forms-insurance-health](https://dependencywatch.io/package/npm/pfp-forms-insurance-health) | npm | 0.0.0 |
| [pfp-forms-sme-loan](https://dependencywatch.io/package/npm/pfp-forms-sme-loan) | npm | 0.0.0 |
| [pfp-forms-sme-sitebuilder](https://dependencywatch.io/package/npm/pfp-forms-sme-sitebuilder) | npm | 0.0.0 |
| [platform-ui-codemods](https://dependencywatch.io/package/npm/platform-ui-codemods) | npm | 0.0.0 |
| [polygon-toolkit-validate](https://dependencywatch.io/package/npm/polygon-toolkit-validate) | npm | 0.0.0 |
| [rallycoding](https://dependencywatch.io/package/npm/rallycoding) | npm | 0.0.0 |
| [rc4-secure](https://dependencywatch.io/package/pypi/rc4-secure) | PyPI | 1.0.0 |
| [sigchain-js](https://dependencywatch.io/package/npm/sigchain-js) | npm | 0.0.0 |
| [test-pkg-pnpm](https://dependencywatch.io/package/npm/test-pkg-pnpm) | npm | 0.0.0 |
| [test-pkg-x0](https://dependencywatch.io/package/npm/test-pkg-x0) | npm | 0.0.0 |
| [test-pkg-yarn](https://dependencywatch.io/package/npm/test-pkg-yarn) | npm | 0.0.0 |
| [tn-advertisement](https://dependencywatch.io/package/npm/tn-advertisement) | npm | 0.0.0 |
| [webpack-cdn-fetcher](https://dependencywatch.io/package/npm/webpack-cdn-fetcher) | npm | 0.0.0 |
| [x6842179305](https://dependencywatch.io/package/npm/x6842179305) | npm | 1.0.0, 1.0.1 |

## What happened

The 24-hour window covering 2026-08-20 published 55 new GHSA CWE-506 advisories (52 npm, 3 PyPI) - the initial 2026-08-20 06:00 UTC pass caught 31, and the 2026-08-21 06:00 UTC backfill (this file's `lastUpdated`) added another 24 dep-confusion, blockchain-toolkit, and create-react-app typosquat advisories published later on 2026-08-20. This is a scattered follow-up to the [2026-08-19 headline sweep](https://dependencywatch.io/incident/multi-2026-08-19-ghsa-malware-sweep) (Sui `@mysten/*` day 6 targeted, Chinese exam-cheat surveillance, jsonspack pino revival). The Sui `@mysten/*` typosquat register (days 1-6 running 2026-08-11 through 2026-08-19) does NOT extend into 2026-08-20 - no new Sui-adjacent GHSAs published in this window, suggesting the operator paused after the day-6 targeted payload triggered the vendor attention it did.

Three items in this window carry material per-package IOCs (rare across a 31-advisory sweep) and drive the file: `libasync` (Windows-registry-persistent cryptominer), `express-route-engine` (jsonbin.io eval-loader), and `base99-85x` (plaintext key exfil). The rest split evenly between PoC/dep-confusion shapes and boilerplate "assume host compromised" advisories.

## Cluster A - PyPI `libasync` cryptominer (1 package)

| Package | Versions | GHSA | Campaign | Payload |
|---|---|---|---|---|
| `libasync` | `<= 1.0.0` | GHSA-7vpc-7xx6-5v47 | `2026-08-libasync` | Downloads and executes remote binary on **import** (not just install); Windows registry persistence; sandbox detection; cryptominer; obfuscated payload inside native extension |

Hashes: `a46929f4…eb9c`, `11d7c6bd…a278`, `b7e770b7…c0d0`.

Campaign identifier ties this to the **[`2026-07-pyqt6darktheme` PyPI cryptominer register](https://github.com/ossf/malicious-packages)** disclosed and tracked by OpenSSF (`kam193`). Same infrastructure shape (Windows-first, native-extension carrier, registry persistence, sandbox-aware), fresh typosquat surface (`libasync` targets the async / asyncio ecosystem). Expect additional siblings under async-adjacent names in the days ahead.

## Cluster B - PyPI `rc4-secure` OpenSSF PoC (1 package)

| Package | Versions | GHSA | Campaign | Payload |
|---|---|---|---|---|
| `rc4-secure` | `1.0.0` | GHSA-q3mh-hmf4-7c8m | `2026-08-rc4-secure` | Downloads and executes remote binary; observed sample fetches an unrelated legitimate binary (consistent with OpenSSF PoC / research canary) |

Hash: `c00d4194…73bd`. The shape is fully weaponisable - a real second-stage URL on a re-publish would compromise every install runner. Treat as if it were a live drop.

Parallel item folded into yesterday's file: `reqcrypt-dev@0.1.0` (GHSA-f4gc-vf6c-945w, hash `8e66755912…f3e4`) is the same `2026-08-reqcrypt` campaign as [reqcrypt from 2026-08-19](https://dependencywatch.io/incident/multi-2026-08-19-ghsa-malware-sweep), just re-published under a `-dev` suffix to survive the reqcrypt takedown. Same HTTP-response `exec()` backdoor.

## Cluster C - npm `express-route-engine` jsonbin.io eval-loader (1 package)

| Package | Versions | GHSA | Payload |
|---|---|---|---|
| `express-route-engine` | `<= 3.6.3` | GHSA-xvv6-j32c-qxhp | On import, fetches JSON blob from `https://api.jsonbin.io/v3/b/6a4f5816f5f4af5e29762c92`, extracts `cerookie` field, `Function()` eval - full Node.js RCE |

Hash: `8f540413…c55d`. Disguised as "normalize-path (ES6 safe version)" with decoy helper functions to defeat casual review. Because `jsonbin.io` bins are **mutable**, the operator can rotate second-stage content without republishing the malicious package - once installed, any future `require('express-route-engine')` (or the module its bundler pulled in) fetches whatever the operator has queued at that bin ID.

`api.jsonbin.io` is a common malware-C2 host in 2026 sweeps because it presents as legitimate SaaS API infrastructure and is not on typical block lists. Add to your DNS RPZ / perimeter deny for build runners unless a specific service explicitly needs it.

## Cluster D - npm `base99-85x` base-x cleartext key exfil (1 package)

| Package | Versions | GHSA | Payload |
|---|---|---|---|
| `base99-85x` | `<= 5.0.2` | GHSA-6h69-gw54-v5hv | Typosquat of `base-x`; overridden `decode()` POSTs every input as JSON to `http://168.231.81.80:3001/api/log` **in cleartext** before returning decoded value |

Hash: `92b7a431…240d`. This is the highest-severity item in the window: `base-x` is a foundational encoding library, and its `decode()` is what callers use to parse base58/base64-encoded **private keys, seed phrases, wallet keystores, and cryptographic secret material**. A project that swapped `base-x` for `base99-85x` has leaked its callers' key material in cleartext to `168.231.81.80` for the entire duration of the exposure - not encrypted, not obfuscated, plain JSON.

The exfil call is inlined into both the CJS and ESM builds, so no module system dodges it. Every developer, CI runner, or production host that ran code through the fake `decode()` while the package was live must be treated as key-compromised.

## Cluster E - npm `mc-provider` Cosmos-registry impersonator (1 package)

| Package | Versions | GHSA | Payload |
|---|---|---|---|
| `mc-provider` | `<= 1.0.10` | GHSA-g2p9-4368-m8g2 | README promises Cosmos chain-registry exports; actual code loads runtime dep `supersig` and re-exports its `HttpProvider` - all wallet/dApp RPC traffic silently redirected through attacker infrastructure |

The payload lives in a transitive dep (`supersig`) named to sound generic, so source-scanning `mc-provider` alone will miss it. Any Cosmos-chain wallet or dApp that pulled `mc-provider` and used its `HttpProvider` sent RPC reads and signed transaction submissions through the operator's server, letting them observe, block, or rewrite in flight.

## Cluster F - npm `x6842179305` XOR-Function dropper (1 package)

| Package | Versions | GHSA | Payload |
|---|---|---|---|
| `x6842179305` | `1.0.0`, `1.0.1` | GHSA-v8r3-5x6v-p289 | Burner numeric name, no README, `1.js` XOR-decodes a keyed byte buffer and `Function()`-evals it on import; `ui.js` uses same decoder shape |

Hash: `ca4cf1d3…5638`. Statically-untypable payload, no benign engineering justification for this shape - assume full RCE on any host that installed it.

## Cluster G - npm `ai-texts-utils` + `ai-texts` bundled obfuscator (2 packages)

| Package | Versions | GHSA | Payload |
|---|---|---|---|
| `ai-texts-utils` | `1.0.3` | GHSA-2gmj-4q5j-qpxf, GHSA-3p3q-38q9-rr37 | Bundled dep literally named `ai-texts` carries obfuscator.io payload: 43-entry rotated string array, custom base64 decoder, `Function()` global capture, self-defending console wrappers; runs at **import** time |
| `ai-texts` | `>= 0` | GHSA-h6w4-w8pj-2pwx | Same bundled component published as standalone package |

Hash for `ai-texts-utils` bundled payload: `a3403480…922c` (Amazon Inspector detection). Because the payload triggers on `require()`, `--ignore-scripts` does not block it. The two GHSAs on `ai-texts-utils` (one malware-classification, one malicious-code) reflect the standard OpenSSF + GitHub-security dual-labeling for the same finding.

## Cluster H - npm dep-confusion PoC families (10 packages)

| Package | GHSA | Suspected target |
|---|---|---|
| `dolyame-ui-form` | GHSA-x6j7-22fv-cjwc | Dolyame (Russian BNPL fintech) |
| `dolyame-boxy-independent-bnpl-info-images` | GHSA-r7x5-x2pm-qx2v | Dolyame |
| `dolyame-boxy-atom-bnpl-store-button` | GHSA-j5r7-jm3x-rgch | Dolyame |
| `fb-forms-form-boilerplate-contacts` | GHSA-rrc5-66g2-j59f | Facebook-style `fb-*` form-boilerplate scope |
| `fb-cards-form-no-resident-information` | GHSA-5gv5-4q77-jc7x | Same `fb-*` scope |
| `devplatform-s3-client` | GHSA-557v-9r2x-4vj7 | Generic `devplatform-*` internal scope |
| `devplatform-spa-testing` | GHSA-w476-3rpv-vw8r | Same |
| `digital-interview-digital-interview-core` | GHSA-q8v7-w9cp-xx9g | Interview-platform vendor `digital-interview-*` |
| `finance-business-company-id-models` | GHSA-mgqh-vwhj-8hqw | Generic finance / business-ID enterprise scope |
| `mc-provider` (also Cluster E) | GHSA-g2p9-4368-m8g2 | Cosmos-registry impersonator |

All ten carry the boilerplate CWE-506 "assume host fully compromised" advisory - no per-package IOC published. The shape is dep-confusion PoC: highly-specific internal-scope names that only match if a private org's `.npmrc` scope precedence misresolved a private package to the public registry. Almost none of these names have any legitimate open-source use case; a public download from any of them is worth investigating as a private-registry misconfiguration.

## Cluster I - npm express + eslint typosquat cluster (5 packages)

| Package | GHSA |
|---|---|
| `express-request-engine` | GHSA-684q-384r-cr7r |
| `express-enrouten-async` | GHSA-25jv-xr7c-mx67 |
| `express-mocha-test` | GHSA-7jq4-grp7-9wq3 |
| `eslint-config-consumerweb` | GHSA-2pxg-969f-jc3q |
| `eslint-commit-parser` | GHSA-qmq6-r6mp-r586 |

All carry only boilerplate CWE-506; no per-package IOC published. Names sit in the exact `express-*-engine` / `express-*-test` / `eslint-config-*` / `eslint-*-parser` space a distracted developer would `npm i` by mistake - low creativity, high traffic-shape.

## Cluster J - npm miscellaneous boilerplate + test/PoC (11 packages)

| Package | GHSA | Notes |
|---|---|---|
| `nano-perf` | GHSA-4236-g67q-42fc | 2026-08-20 boilerplate |
| `tn-advertisement` | GHSA-j2c8-6hx3-7994 | 2026-08-20 boilerplate |
| `node-runtime-utils` | GHSA-c436-rrhg-m984 | Runtime-utils typosquat surface |
| `fetchcraft` | GHSA-fg76-g9g4-9xpr | fetch-adjacent typosquat |
| `webpack-cdn-fetcher` | GHSA-gjvp-mjhq-rfwc | webpack ecosystem name-shape |
| `fe-utils-core` | GHSA-8xf7-7m4f-fgrv | Frontend-utils typosquat |
| `filewisee` | GHSA-wp6h-28pg-v4j5 | Generic file-* typosquat |
| `griffin-transliterator` | GHSA-4hcm-p7x4-q9h9 | Transliterator library name |
| `emojifancy-print` | GHSA-46c9-x7v7-2g5h | Emoji-* typosquat |
| `bunnyhijack-test-0x00` | GHSA-8x5v-wf85-xhj5 | **Research canary** - should not appear in production |
| `test-pkg-yarn` | GHSA-r653-6655-p467 | **Research canary** |
| `test-pkg-x0` | GHSA-45jm-p8g6-hcxf | **Research canary** |
| `test-pkg-pnpm` | GHSA-7grv-5j2w-4wx3 | **Research canary** |
| `evil-pkg` | GHSA-p67r-jq7p-6g7v | **Research canary** |

The last five carry names that read as OpenSSF / researcher canaries - `test-pkg-*`, `evil-pkg`, `bunnyhijack-test-*`. If any appear in a production lockfile it is not because a developer needed them; it is because someone added a research URL or a copy-paste sample as a real dep, and the transitive chain should be audited for whatever context brought them in.

## Registry state

All 31 packages yanked from their respective registries (npm, PyPI) during the takedown windows on 2026-08-19 late and 2026-08-20. Private mirrors that cached tarballs before takedown will keep serving them.

## Related tracked activity

- **`2026-07-pyqt6darktheme` PyPI cryptominer register** (Cluster A): now extends with `libasync` as a new typosquat surface. Same infrastructure, same discovery credit (`kam193`), same Windows-registry-persistent shape.
- **`2026-08-reqcrypt` PyPI HTTP-response backdoor** (Cluster B parallel): sibling `reqcrypt-dev` folded into [yesterday's file](https://dependencywatch.io/incident/multi-2026-08-19-ghsa-malware-sweep) rather than duplicated here.
- **Sui `@mysten/*` typosquat multi-day register** (days 1-6 running 2026-08-11 through 2026-08-19): does NOT extend into 2026-08-20 - no Sui-adjacent GHSAs in this window.
- **jsonspack pino-typosquat operator** (Cluster C of 2026-08-19): no new siblings in this window.
- Discovery credits: `GitHub Advisory Database`, `OpenSSF malicious-packages`, `OpenSSF Package Analysis`, `Amazon Inspector`, `kam193`. No named threat actor.

## Impact

- **Cluster A - PyPI `libasync` cryptominer (2026-08-20)**: `libasync@<=1.0.0` (GHSA-7vpc-7xx6-5v47, campaign `2026-08-libasync`, hashes `a46929f4ba4ca97beaf5511f0be0af36c4d1e9deff65bea3821137c2c258eb9c` / `11d7c6bd095b62206bc5b49b6749dfc73ea21e9b5b0b268c84ef4cadd1cba278` / `b7e770b71209bbc615ae928de01b04aef48295bf6548fd5f6d6cfffce531c0d0`). Downloads and executes a remote binary during **import** (not just install), establishes persistence via Windows registry modification, hides payload inside a native extension, includes sandbox-detection logic, and runs as a **cryptomining agent** on the host. Discovery credit and campaign identifier tie this to the multi-week `2026-07-pyqt6darktheme` PyPI cryptominer register catalogued by OpenSSF (`kam193`) - same infrastructure, new typosquat surface
- **Cluster B - PyPI `rc4-secure` OpenSSF PoC (2026-08-19 late)**: `rc4-secure@1.0.0` (GHSA-q3mh-hmf4-7c8m, campaign `2026-08-rc4-secure`, hash `c00d4194b32151e318678fb20166e9023d74acbed43e4a9d82f7834569cb73bd`). Downloads and executes a remote binary on install; observed sample fetches an unrelated legitimate binary, consistent with an **OpenSSF PoC / research canary** rather than a weaponised drop, but the shape is a fully weaponisable remote-exec dropper and any republish with a real second-stage URL would compromise every installer. The parallel `reqcrypt-dev@0.1.0` (GHSA-f4gc-vf6c-945w, campaign `2026-08-reqcrypt`, hash `8e66755912c02a4de1ed6f86b092e2a0dcdadbcaef931cbd07c6d2306619f3e4`) is folded into yesterday's [2026-08-19 sweep](https://dependencywatch.io/incident/multi-2026-08-19-ghsa-malware-sweep) Cluster H as the reqcrypt sibling
- **Cluster C - npm `express-route-engine` jsonbin.io eval-loader (2026-08-20)**: `express-route-engine@<=3.6.3` (GHSA-xvv6-j32c-qxhp, hash `8f54041362d71f16d1ee889c3992558cec28371030eaca4a3962ac0e9e3ec55d`). On import, fetches a JSON blob from `https://api.jsonbin.io/v3/b/6a4f5816f5f4af5e29762c92`, extracts a field named `cerookie`, and executes it via indirect `Function` constructor lookup - full Node.js RCE. The loader is disguised as "normalize-path (ES6 safe version)" with decoy helper functions to defeat casual code review. Because the payload URL is a mutable `jsonbin.io` bin, the operator can rotate second-stage content without republishing the package
- **Cluster D - npm `base99-85x` base-x cleartext key exfil (2026-08-19 late)**: `base99-85x@<=5.0.2` (GHSA-6h69-gw54-v5hv, hash `92b7a4319eaf4f75e0e4138802a61018a4016e0b1ff69e9e8eab51eeb01a240d`). Typosquat of the widely-used `base-x` module; the overridden `decode()` function **POSTs every caller-supplied input as JSON to `http://168.231.81.80:3001/api/log` in cleartext before returning the decoded value**. Because base-x callers commonly pass base58/base64-encoded wallet private keys, seed phrases, and cryptographic material, any project that swapped in `base99-85x` has leaked its callers' key material to the operator. The exfil path is inlined in both CJS and ESM builds so no module system dodges it
- **Cluster E - npm `mc-provider` Cosmos-registry impersonator (2026-08-19 late)**: `mc-provider@<=1.0.10` (GHSA-g2p9-4368-m8g2). README falsely promises Cosmos chain-registry exports (`assets`, `chains`, `ibc`); actual code dynamically loads a runtime dependency named `supersig` and re-exports its `HttpProvider`. Wallet and dApp code that thought it was talking to a Cosmos RPC provider is silently redirected through an attacker-controlled HTTP/RPC provider - **every signed transaction and RPC read is now visible to and rewritable by the operator**. The malicious payload lives in the `supersig` transitive dep, so scanning `mc-provider` source alone misses it
- **Cluster F - npm `x6842179305` XOR-Function dropper (2026-08-19 late)**: `x6842179305@1.0.0,1.0.1` (GHSA-v8r3-5x6v-p289, hash `ca4cf1d317cc7c96f8007c983999e18529f2cb8dea5514dcc68f704c7bda5638`). Burner-style numeric package name, no README, no legitimate API surface; entry file `1.js` XOR-decodes a keyed byte buffer and passes the result to the `Function` constructor, executing arbitrary code on module import. Companion file `ui.js` uses the same decoder shape. The static-untypable payload cannot be safely analysed without dynamic instrumentation - **treat every install as full RCE**
- **Cluster G - npm `ai-texts-utils`+`ai-texts` bundled obfuscator payload (2026-08-19 late)**: `ai-texts-utils@1.0.3` (GHSA-2gmj-4q5j-qpxf, hash `a340348046b89bf8c446a31a4f48233ec4e0bc412f531db713f54f35c6ea922c`; parallel malware-classification GHSA-3p3q-38q9-rr37) and `ai-texts@>=0` (GHSA-h6w4-w8pj-2pwx). `ai-texts-utils` ships a bundled dependency literally named `ai-texts` containing obfuscator.io-grade code: 43-entry rotated string array, custom base64 decoder, `Function()` global capture, self-defending/debug-protection wrappers around console. Executes at import time on any host that pulls `ai-texts-utils` - the standalone `ai-texts` GHSA covers the bundled component published under its own name too
- **Cluster H - npm dep-confusion PoC families (20 packages, 2026-08-19 late through 2026-08-20)**: A batch of same-day GHSA-classified npm packages whose names read as **internal-scope dep-confusion bait** against specific orgs, each shipping the boilerplate CWE-506 "full compromise" advisory: **Dolyame** (Russian BNPL fintech) - `dolyame-ui-form`, `dolyame-boxy-independent-bnpl-info-images`, `dolyame-boxy-atom-bnpl-store-button`, `dolyame-boxy-desktop-bnpl-card-panel`; **Facebook-style `fb-*` form-boilerplate** - `fb-forms-form-boilerplate-contacts`, `fb-cards-form-no-resident-information`; **generic `devplatform-*`** - `devplatform-s3-client`, `devplatform-spa-testing`, `devplatform-api-clients`, `platform-ui-codemods`; **generic `digital-interview-*`** - `digital-interview-digital-interview-core`; **generic finance-* / hr-* recon** - `finance-business-company-id-models`, `goldstar-api-server`; **`pfp-*` / `pfa-*` financial-forms scope** - `pfp-forms-sme-sitebuilder`, `pfp-forms-sme-loan`, `pfp-forms-insurance-health`, `pfp-forms-independent-sme-glossary-anchor`, `pfp-block-mobile-steps`, `pfa-errors`; **`bigops-*` DevOps-tooling scope** - `bigops-watchdog-angular`, `bigops-umf-statist`. Advisories lack per-package IOCs but the highly-specific internal-name shape is the fingerprint - assume any org whose private `.npmrc` scope precedence resolved one of these to the public registry has been recon'd
- **Cluster I - npm express + eslint + create-react-app + blockchain-toolkit typosquat cluster (14 packages, 2026-08-19 late through 2026-08-20)**: `express-request-engine@>=0` (GHSA-684q-384r-cr7r), `express-enrouten-async@>=0` (GHSA-25jv-xr7c-mx67), `express-mocha-test@>=0` (GHSA-7jq4-grp7-9wq3), `eslint-config-consumerweb@>=0` (GHSA-2pxg-969f-jc3q), `eslint-commit-parser@>=0` (GHSA-qmq6-r6mp-r586), `create-react-app-text@>=0` (GHSA-9324-2pfx-4w9r), `create-react-app-ux@>=0` (GHSA-rxpg-3mx3-fwqm), `create-react-app-ui@>=0` (GHSA-qvrq-vg6m-5cr8), `sigchain-js@>=0` (GHSA-xq2c-h4ch-xmwj), `exam-kit@>=0` (GHSA-3g8c-37c3-75vv), `@pablo_clueless/sniffr@>=0` (GHSA-2gvc-mrh5-885x), `@pablo_clueless/printr@>=0` (GHSA-3jxq-xch2-6hpm), `ethereum-validator@>=0` (GHSA-f4c6-m557-c5qf), `polygon-toolkit-validate@>=0` (GHSA-w4vh-7827-g474). All ship the boilerplate CWE-506 "assume host fully compromised" advisory with no per-package IOC published. Naming targets the express/eslint/create-react-app ecosystems, plus **blockchain-toolkit typosquat surface (`ethereum-validator`, `polygon-toolkit-validate`)** that a Web3 developer would casually `npm i` when reaching for a signer or validator utility
- **Cluster J - npm miscellaneous boilerplate malware (13 packages, 2026-08-19 late through 2026-08-20)**: `nano-perf@>=0` (GHSA-4236-g67q-42fc, 2026-08-20), `tn-advertisement@>=0` (GHSA-j2c8-6hx3-7994, 2026-08-20), `node-runtime-utils@>=0` (GHSA-c436-rrhg-m984), `fetchcraft@>=0` (GHSA-fg76-g9g4-9xpr), `webpack-cdn-fetcher@>=0` (GHSA-gjvp-mjhq-rfwc), `fe-utils-core@>=0` (GHSA-8xf7-7m4f-fgrv), `filewisee@>=0` (GHSA-wp6h-28pg-v4j5), `griffin-transliterator@>=0` (GHSA-4hcm-p7x4-q9h9), `emojifancy-print@>=0` (GHSA-46c9-x7v7-2g5h), `optimize-regex@>=0` (GHSA-vrj5-6f7q-fx9g), `rallycoding@>=0` (GHSA-xh99-h4gh-gcv6), `o3forms@>=0` (GHSA-gp6v-h28c-4fxf), plus test/researcher-shape `bunnyhijack-test-0x00@>=0` (GHSA-8x5v-wf85-xhj5), `test-pkg-yarn@>=0` (GHSA-r653-6655-p467), `test-pkg-x0@>=0` (GHSA-45jm-p8g6-hcxf), `test-pkg-pnpm@>=0` (GHSA-7grv-5j2w-4wx3), `evil-pkg@>=0` (GHSA-p67r-jq7p-6g7v). All are CWE-506-classified with the "assume host fully compromised" boilerplate. The `test-pkg-*` / `evil-pkg` / `bunnyhijack-test-*` names are OpenSSF / researcher canaries - they should NEVER appear in a production lockfile; if they do, someone added a research URL as a real dep

## What to do

1. Grep every lockfile (`package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `requirements.txt`, `Pipfile.lock`, `poetry.lock`, `uv.lock`) for the 31 package names below
2. **For Cluster A matches (`libasync` PyPI cryptominer)**: uninstall from every virtualenv and **reimage Windows hosts** - the malware sets registry persistence and runs a cryptomining agent, so removing the pip package alone does not stop the mining. Audit Task Scheduler, Startup folder, `HKCU\Software\Microsoft\Windows\CurrentVersion\Run`, and `HKLM\...\Run` for anomalous entries. Check for high sustained CPU on hosts that installed libasync between the publish date and takedown. Cross-reference the [2026-07 `pyqt6darktheme` cryptominer register](https://github.com/ossf/malicious-packages) - if your ML/scientific-Python environments matched libasync, they may also match the earlier campaign names
3. **For Cluster B matches (`rc4-secure`)**: uninstall. The observed sample looks PoC-shaped, but assume a weaponised republish already ran on any host that installed it before takedown; rotate credentials the host could reach as a precaution
4. **For Cluster C matches (`express-route-engine`)**: uninstall and rotate every credential the Node.js process could touch - the `Function()` loader gets full Node capability. Block outbound to `api.jsonbin.io` at the perimeter from every build runner unless a specific service explicitly needs it - `jsonbin.io` is a common malware-C2 host because it looks legitimate and is rarely denylisted
5. **For Cluster D matches (`base99-85x` base-x typosquat)**: uninstall and correct to the real `base-x` package. **Treat every private key, seed phrase, wallet keystore, and cryptographic secret the application handled while `base99-85x` was in the dep tree as leaked** - the operator has plaintext copies at `168.231.81.80`. Rotate wallet keys, generate fresh seed phrases, migrate funds to fresh addresses. Block egress to `168.231.81.80` at the perimeter and via DNS RPZ so that any lingering install can no longer exfil
6. **For Cluster E matches (`mc-provider` Cosmos impersonator)**: uninstall and correct to the actual `@cosmos-kit/*` / `chain-registry` package the project meant to use. **Audit every signed Cosmos-chain transaction the affected app produced during the exposure window** - the operator's HttpProvider could rewrite RPC responses used to derive tx bodies. Also remove the transitive `supersig` package if pinned
7. **For Cluster F matches (`x6842179305`)**: uninstall, treat host as fully compromised, rotate all credentials, reimage build runners on any hit. A numeric-burner package name that XOR-decodes a Function-constructor payload has no benign use case
8. **For Cluster G matches (`ai-texts-utils` / `ai-texts`)**: uninstall from every project. Because the payload runs at **import** (not postinstall), `--ignore-scripts` does NOT block it - the first `require('ai-texts-utils')` runs the obfuscator payload. Rotate cloud credentials on any host that ever imported either package; correct to whichever legitimate text-normalisation library the developer meant
9. **For Cluster H matches (dep-confusion PoC families)**: uninstall each. If your `.npmrc` scope precedence caused a private `dolyame-*` / `fb-*` / `devplatform-*` / `digital-interview-*` / `finance-*` package to resolve to the public registry, fix the precedence (`registry=` for the private mirror, `always-auth=true`, and scoped `@scope:registry=` for public scopes only) and audit the manifest for other private-scope names that could get hijacked. Treat any install as full RCE until proven otherwise
10. **For Cluster I matches (express/eslint typosquat)**: uninstall each. Even though these carry only the boilerplate CWE-506 advisory (no per-package IOC published), the operator surface (`express-*-engine`, `eslint-config-*`) is the exact space a distracted developer would `npm i` by mistake; correct to the real dependency and treat any install as full RCE
11. **For Cluster J matches (miscellaneous boilerplate + test/PoC)**: uninstall each. If a `test-pkg-*`, `evil-pkg`, or `bunnyhijack-test-*` appears in a production lockfile, treat as an unauthorised research-canary insertion and rotate credentials on the host - a real dependency should never carry that name
12. For all npm installs in CI, run with `--ignore-scripts` as defence-in-depth - but note it does NOT stop Clusters C, D, E, G, or F (they trigger on import/require, not postinstall). For all `pip install` runs, prefer `--only-binary=:all:` where feasible to skip `setup.py` execution
13. Verify none of the 31 packages still resolves via your private mirror - internal caches routinely keep serving yanked tarballs after the public takedown

## Check your own dependencies

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

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

## References

- [GHSA-7vpc-7xx6-5v47 - libasync (PyPI cryptominer, 2026-08-libasync campaign)](https://github.com/advisories/GHSA-7vpc-7xx6-5v47) - GitHub
- [GHSA-q3mh-hmf4-7c8m - rc4-secure (PyPI OpenSSF PoC dropper)](https://github.com/advisories/GHSA-q3mh-hmf4-7c8m) - GitHub
- [GHSA-f4gc-vf6c-945w - reqcrypt-dev (PyPI, folded into 2026-08-19 sweep Cluster H)](https://github.com/advisories/GHSA-f4gc-vf6c-945w) - GitHub
- [GHSA-xvv6-j32c-qxhp - express-route-engine (npm jsonbin.io eval-loader)](https://github.com/advisories/GHSA-xvv6-j32c-qxhp) - GitHub
- [GHSA-6h69-gw54-v5hv - base99-85x (npm base-x typosquat, plaintext key exfil to 168.231.81.80)](https://github.com/advisories/GHSA-6h69-gw54-v5hv) - GitHub
- [GHSA-g2p9-4368-m8g2 - mc-provider (npm Cosmos-registry impersonator, supersig transitive dropper)](https://github.com/advisories/GHSA-g2p9-4368-m8g2) - GitHub
- [GHSA-v8r3-5x6v-p289 - x6842179305 (npm XOR-Function dropper)](https://github.com/advisories/GHSA-v8r3-5x6v-p289) - GitHub
- [GHSA-2gmj-4q5j-qpxf - ai-texts-utils (npm bundled obfuscator payload)](https://github.com/advisories/GHSA-2gmj-4q5j-qpxf) - GitHub
- [GHSA-3p3q-38q9-rr37 - ai-texts-utils (parallel malware classification)](https://github.com/advisories/GHSA-3p3q-38q9-rr37) - GitHub
- [GHSA-h6w4-w8pj-2pwx - ai-texts (npm standalone republish of bundled component)](https://github.com/advisories/GHSA-h6w4-w8pj-2pwx) - GitHub
- [GHSA-x6j7-22fv-cjwc - dolyame-ui-form (Dolyame dep-confusion)](https://github.com/advisories/GHSA-x6j7-22fv-cjwc) - GitHub
- [GHSA-r7x5-x2pm-qx2v - dolyame-boxy-independent-bnpl-info-images](https://github.com/advisories/GHSA-r7x5-x2pm-qx2v) - GitHub
- [GHSA-j5r7-jm3x-rgch - dolyame-boxy-atom-bnpl-store-button](https://github.com/advisories/GHSA-j5r7-jm3x-rgch) - GitHub
- [GHSA-rrc5-66g2-j59f - fb-forms-form-boilerplate-contacts (fb-* dep-confusion)](https://github.com/advisories/GHSA-rrc5-66g2-j59f) - GitHub
- [GHSA-5gv5-4q77-jc7x - fb-cards-form-no-resident-information](https://github.com/advisories/GHSA-5gv5-4q77-jc7x) - GitHub
- [GHSA-557v-9r2x-4vj7 - devplatform-s3-client (devplatform-* dep-confusion)](https://github.com/advisories/GHSA-557v-9r2x-4vj7) - GitHub
- [GHSA-w476-3rpv-vw8r - devplatform-spa-testing](https://github.com/advisories/GHSA-w476-3rpv-vw8r) - GitHub
- [GHSA-q8v7-w9cp-xx9g - digital-interview-digital-interview-core (dep-confusion)](https://github.com/advisories/GHSA-q8v7-w9cp-xx9g) - GitHub
- [GHSA-mgqh-vwhj-8hqw - finance-business-company-id-models (dep-confusion)](https://github.com/advisories/GHSA-mgqh-vwhj-8hqw) - GitHub
- [GHSA-684q-384r-cr7r - express-request-engine (express-* typosquat)](https://github.com/advisories/GHSA-684q-384r-cr7r) - GitHub
- [GHSA-25jv-xr7c-mx67 - express-enrouten-async](https://github.com/advisories/GHSA-25jv-xr7c-mx67) - GitHub
- [GHSA-7jq4-grp7-9wq3 - express-mocha-test](https://github.com/advisories/GHSA-7jq4-grp7-9wq3) - GitHub
- [GHSA-2pxg-969f-jc3q - eslint-config-consumerweb (eslint-* typosquat)](https://github.com/advisories/GHSA-2pxg-969f-jc3q) - GitHub
- [GHSA-qmq6-r6mp-r586 - eslint-commit-parser](https://github.com/advisories/GHSA-qmq6-r6mp-r586) - GitHub
- [GHSA-4236-g67q-42fc - nano-perf (2026-08-20 boilerplate)](https://github.com/advisories/GHSA-4236-g67q-42fc) - GitHub
- [GHSA-j2c8-6hx3-7994 - tn-advertisement (2026-08-20 boilerplate)](https://github.com/advisories/GHSA-j2c8-6hx3-7994) - GitHub
- [GHSA-c436-rrhg-m984 - node-runtime-utils](https://github.com/advisories/GHSA-c436-rrhg-m984) - GitHub
- [GHSA-fg76-g9g4-9xpr - fetchcraft](https://github.com/advisories/GHSA-fg76-g9g4-9xpr) - GitHub
- [GHSA-gjvp-mjhq-rfwc - webpack-cdn-fetcher](https://github.com/advisories/GHSA-gjvp-mjhq-rfwc) - GitHub
- [GHSA-8xf7-7m4f-fgrv - fe-utils-core](https://github.com/advisories/GHSA-8xf7-7m4f-fgrv) - GitHub
- [GHSA-wp6h-28pg-v4j5 - filewisee](https://github.com/advisories/GHSA-wp6h-28pg-v4j5) - GitHub
- [GHSA-4hcm-p7x4-q9h9 - griffin-transliterator](https://github.com/advisories/GHSA-4hcm-p7x4-q9h9) - GitHub
- [GHSA-46c9-x7v7-2g5h - emojifancy-print](https://github.com/advisories/GHSA-46c9-x7v7-2g5h) - GitHub
- [GHSA-8x5v-wf85-xhj5 - bunnyhijack-test-0x00 (research canary shape)](https://github.com/advisories/GHSA-8x5v-wf85-xhj5) - GitHub
- [GHSA-r653-6655-p467 - test-pkg-yarn (research canary)](https://github.com/advisories/GHSA-r653-6655-p467) - GitHub
- [GHSA-45jm-p8g6-hcxf - test-pkg-x0 (research canary)](https://github.com/advisories/GHSA-45jm-p8g6-hcxf) - GitHub
- [GHSA-7grv-5j2w-4wx3 - test-pkg-pnpm (research canary)](https://github.com/advisories/GHSA-7grv-5j2w-4wx3) - GitHub
- [GHSA-p67r-jq7p-6g7v - evil-pkg (research canary)](https://github.com/advisories/GHSA-p67r-jq7p-6g7v) - GitHub
- [GHSA-c75h-f786-3xrc - dolyame-boxy-desktop-bnpl-card-panel (2026-08-20 late)](https://github.com/advisories/GHSA-c75h-f786-3xrc) - GitHub
- [GHSA-rphm-c9jq-j4f6 - devplatform-api-clients](https://github.com/advisories/GHSA-rphm-c9jq-j4f6) - GitHub
- [GHSA-wc85-c9g8-72g6 - platform-ui-codemods](https://github.com/advisories/GHSA-wc85-c9g8-72g6) - GitHub
- [GHSA-mm54-9954-hrcp - bigops-watchdog-angular](https://github.com/advisories/GHSA-mm54-9954-hrcp) - GitHub
- [GHSA-65hm-c5q4-xqrc - bigops-umf-statist](https://github.com/advisories/GHSA-65hm-c5q4-xqrc) - GitHub
- [GHSA-w5wj-pp55-835w - goldstar-api-server](https://github.com/advisories/GHSA-w5wj-pp55-835w) - GitHub
- [GHSA-x4j8-fqq2-qv3q - pfp-forms-sme-sitebuilder](https://github.com/advisories/GHSA-x4j8-fqq2-qv3q) - GitHub
- [GHSA-p37j-6hr3-m2q3 - pfp-forms-sme-loan](https://github.com/advisories/GHSA-p37j-6hr3-m2q3) - GitHub
- [GHSA-262x-3pgh-mxj5 - pfp-forms-insurance-health](https://github.com/advisories/GHSA-262x-3pgh-mxj5) - GitHub
- [GHSA-fg28-xw73-5q8v - pfp-forms-independent-sme-glossary-anchor](https://github.com/advisories/GHSA-fg28-xw73-5q8v) - GitHub
- [GHSA-627r-73p5-f9mm - pfp-block-mobile-steps](https://github.com/advisories/GHSA-627r-73p5-f9mm) - GitHub
- [GHSA-c4mr-v4hr-px3m - pfa-errors](https://github.com/advisories/GHSA-c4mr-v4hr-px3m) - GitHub
- [GHSA-xq2c-h4ch-xmwj - sigchain-js](https://github.com/advisories/GHSA-xq2c-h4ch-xmwj) - GitHub
- [GHSA-3g8c-37c3-75vv - exam-kit](https://github.com/advisories/GHSA-3g8c-37c3-75vv) - GitHub
- [GHSA-2gvc-mrh5-885x - @pablo_clueless/sniffr](https://github.com/advisories/GHSA-2gvc-mrh5-885x) - GitHub
- [GHSA-3jxq-xch2-6hpm - @pablo_clueless/printr](https://github.com/advisories/GHSA-3jxq-xch2-6hpm) - GitHub
- [GHSA-f4c6-m557-c5qf - ethereum-validator (blockchain-toolkit typosquat)](https://github.com/advisories/GHSA-f4c6-m557-c5qf) - GitHub
- [GHSA-w4vh-7827-g474 - polygon-toolkit-validate (blockchain-toolkit typosquat)](https://github.com/advisories/GHSA-w4vh-7827-g474) - GitHub
- [GHSA-9324-2pfx-4w9r - create-react-app-text](https://github.com/advisories/GHSA-9324-2pfx-4w9r) - GitHub
- [GHSA-rxpg-3mx3-fwqm - create-react-app-ux](https://github.com/advisories/GHSA-rxpg-3mx3-fwqm) - GitHub
- [GHSA-qvrq-vg6m-5cr8 - create-react-app-ui](https://github.com/advisories/GHSA-qvrq-vg6m-5cr8) - GitHub
- [GHSA-vrj5-6f7q-fx9g - optimize-regex](https://github.com/advisories/GHSA-vrj5-6f7q-fx9g) - GitHub
- [GHSA-xh99-h4gh-gcv6 - rallycoding](https://github.com/advisories/GHSA-xh99-h4gh-gcv6) - GitHub
- [GHSA-gp6v-h28c-4fxf - o3forms](https://github.com/advisories/GHSA-gp6v-h28c-4fxf) - GitHub
- [GitHub Advisory Database - recent npm malware advisories](https://github.com/advisories?query=type%3Amalware+ecosystem%3Anpm&sort=published-desc) - GitHub
- [GitHub Advisory Database - recent pip malware advisories](https://github.com/advisories?query=type%3Amalware+ecosystem%3Apip&sort=published-desc) - GitHub

---

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