# GitHub Advisory malware sweep, 4 September 2026

> 10-package npm-only sweep. Two remote-tarball hijack clusters (`@bx-ui-framework/*` via `artifactorymanager.com`/`remoteknight.com`; `@grab-food/order-sdk-web`+`lil-swisgom-hlepers` via `grivy-packages.com`), `wallet-watcher` BIP-39/ETH-key AES-256-GCM stealer, dep-confusion recon (OKX + Avigilon), and `vitest-cli-dev` remote-`new Function()` dropper.

- Published: 2026-09-04
- 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: 10 packages, 24 compromised versions
- Tags: dependency-confusion, credential-theft, infostealer, crypto-wallet-drain, typosquat, obfuscation, ci-cd-compromise
- Also known as: 2026-09-04 GHSA sweep, bx-ui-framework artifactorymanager remote-tarball hijack, grivy-packages.com remote-tarball hijack, wallet-watcher BIP-39 ETH stealer, vitest-cli-dev remote new Function dropper
- Detected by: GitHub Advisory Database, OpenSSF malicious-packages, OpenSSF Package Analysis, Amazon Inspector
- Incident ID: multi-2026-09-04-ghsa-malware-sweep

## Affected packages (10)

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

| Package | Ecosystem | Compromised versions |
|---|---|---|
| [@avigilon/node-webrtc](https://dependencywatch.io/package/npm/@avigilon/node-webrtc) | npm | 2.1.4, 2.1.5 |
| [@bx-ui-framework/authentication](https://dependencywatch.io/package/npm/@bx-ui-framework/authentication) | npm | 1.2.0, 15.0.0 |
| [@bx-ui-framework/common](https://dependencywatch.io/package/npm/@bx-ui-framework/common) | npm | 1.2.0, 15.0.0 |
| [@bx-ui-framework/microfrontend](https://dependencywatch.io/package/npm/@bx-ui-framework/microfrontend) | npm | 15.0.0 |
| [@grab-food/order-sdk-web](https://dependencywatch.io/package/npm/@grab-food/order-sdk-web) | npm | 49.9.9 |
| [@yuva2210/okx-poc-rce-impact](https://dependencywatch.io/package/npm/@yuva2210/okx-poc-rce-impact) | npm | 2.0.0 |
| [lil-swisgom-hlepers](https://dependencywatch.io/package/npm/lil-swisgom-hlepers) | npm | 49.9.9 |
| [mcp-consultasdeveiculos-client](https://dependencywatch.io/package/npm/mcp-consultasdeveiculos-client) | npm | 0.0.2, 0.1.0, 0.1.1 |
| [vitest-cli-dev](https://dependencywatch.io/package/npm/vitest-cli-dev) | npm | 10.0.0, 10.0.1, 10.0.2, 10.0.3, 10.0.4, 10.0.5, 10.0.6, 10.0.7 |
| [wallet-watcher](https://dependencywatch.io/package/npm/wallet-watcher) | npm | 1.0.0, 1.0.1, 1.0.2 |

## What happened

The 24-hour window ending 2026-09-04 published 10 new npm malware advisories and **zero new PyPI ones** - all PyPI activity for the day rolled up under the already-catalogued Sept 3 `2026-09-telemetry-helper` campaign. The npm day breaks into six clusters, all published by the GitHub Advisory Database on Sept 4 and sourced through OpenSSF `malicious-packages` + Amazon Inspector + OpenSSF Package Analysis feeds.

Two of the six clusters are the same TTP class - **package.json declaring a runtime dependency as a bare HTTPS URL to an attacker-controlled tarball host**. This is a lower-effort variant of the classic install-script credential steal because the visible npm tarball is empty; the malicious code is fetched from the operator's host at install time and can be silently rotated between installs. Static scanners auditing the npm registry copy see nothing.

## Cluster A - `@bx-ui-framework/*` bare-URL remote-tarball dep-confusion (3 packages)

| Package | Versions | GHSA | Tarball host |
|---|---|---|---|
| `@bx-ui-framework/microfrontend` | `15.0.0` | GHSA-v4h4-57j3-83rp | `repo.artifactorymanager.com` |
| `@bx-ui-framework/authentication` | `1.2.0`, `15.0.0` | GHSA-9q5c-jq8f-775p | `repo.artifactorymanager.com` |
| `@bx-ui-framework/common` | `1.2.0`, `15.0.0` | GHSA-m2pp-gxpx-9chq | `repo.remoteknight.com` |

Each package.json declares its dependency as a bare `https://<attacker-host>/<path>` URL - no version, no integrity hash, no signature. On `npm install`, npm fetches whatever bytes the operator serves and executes any lifecycle scripts they contain. The `@bx-ui-framework` scope has no verified enterprise publisher on npm; the operator picked a plausible dep-confusion scope name and used two different attacker hosts across three packages (a light attempt to defeat host-based domain blocklists).

**Why the pattern is dangerous**: because the tarball is fetched fresh on every install, a poisoned lockfile does not preserve the payload for forensic replay. A rebuild against a mirror that no longer serves the URL yields a "clean" install even though a compromised host has already executed the operator's code once. Assume worst-case for any host that install-scripted these packages in the exposure window.

## Cluster B - `grivy-packages.com` remote-tarball hijack (2 packages)

| Package | Versions | GHSA | Tarball host | Target scope |
|---|---|---|---|---|
| `@grab-food/order-sdk-web` | `49.9.9` | GHSA-84w3-v779-4w52 | `registry.grivy-packages.com` | Grab (SEA super-app) |
| `lil-swisgom-hlepers` | `49.9.9` | GHSA-wqg5-6mgg-v9gq | `registry.grivy-packages.com` | typo of `swisgom-helpers` |

Same attacker host, same `49.9.9` pinned tag on both packages - one operator. `index.js` is an empty stub; the entire behaviour lives in the `-core` dependency tarball fetched from `grivy-packages.com`. `@grab-food/order-sdk-web` targets Grab internal dep-confusion; `lil-swisgom-hlepers` mistypes the legitimate name to catch fat-fingering developers.

## Cluster C - Dep-confusion reconnaissance drops (2 packages)

| Package | Versions | GHSA | Target scope | Exfil channel |
|---|---|---|---|---|
| `@yuva2210/okx-poc-rce-impact` | `2.0.0` | GHSA-rvf4-r4vv-m3v8 | OKX (crypto exchange) internal | `/tmp/okx-poc-rce-proof.json` (local marker, no network) |
| `@avigilon/node-webrtc` | `2.1.4`, `2.1.5` | GHSA-qm5q-ggwg-5m4q | Avigilon/Motorola video-surveillance internal | `*.burp.attack.live` OAST callback |

Both are recon PoCs, not weaponised implants. The OKX PoC does not phone home - it writes a proof marker to `/tmp` for the attacker to correlate later (perhaps via a follow-up drop that reads the marker, or via manual review of accessible dev hosts). The Avigilon package uses `burp.attack.live` - a Burp Collaborator-style out-of-band callback service - to detect installs without a distinctive C2 host.

**These are not the attack.** They are the fingerprinter that tells the operator which internal namespaces resolve to public npm on their target's network. If either package fired on your infrastructure, the follow-up weaponised drop is coming in the next 2-14 days.

## Cluster D - `wallet-watcher` BIP-39/ETH-key AES-256-GCM stealer (1 package)

| Package | Versions | GHSA |
|---|---|---|
| `wallet-watcher` | `<=1.0.2` | GHSA-fvcm-93j7-7f35 |

**Attack chain**:

1. `npm install wallet-watcher` → postinstall `src/scan.cjs` runs
2. Walks the project tree **starting three directory levels above `node_modules`** - this is deliberate: it escapes past nested `node_modules/wallet-watcher/node_modules/...` layouts and touches the real workspace root
3. Greps `.env`, `.js`, `.ts`, `.json`, `.py`, `.yml`, and keystore files for: BIP-39 wallet mnemonics, 0x-prefixed 64-hex Ethereum private keys, and assignments matching `secret`/`api_key`/`mnemonic`
4. AES-256-GCM-encrypts findings with a **hardcoded key** (traffic decryptable once the key is extracted from the tarball)
5. Tags payload with host+username hash and POSTs to the operator
6. **Also runs at runtime**: the exported `getBalances()` function re-invokes the scanner against the caller's CWD on every call - so `--ignore-scripts` does not defeat it, only removing the package does

The three-levels-up scan and the runtime-callback fallback are the two features that make this one worse than the average preinstall stealer. Any developer laptop that installed AND ever imported `wallet-watcher` has surrendered every crypto wallet whose seed or private key sat in the workspace tree.

## Cluster E - `mcp-consultasdeveiculos-client` CLI-token OOB exfil (1 package)

| Package | Versions | GHSA | Exfil |
|---|---|---|---|
| `mcp-consultasdeveiculos-client` | `0.0.2`, `0.1.0`, `0.1.1` | GHSA-fp7g-2255-xxrp | `*.oob.lyomeri.com/npm-exec` |

The package README **falsely claims "contains NO code and NO install scripts"**. In fact, `bin/main` runs on `npx -y mcp-consultasdeveiculos-client --token <value>` and exfils the full argv (including the `--token` value) alongside hostname, username, OS platform/arch, Node version, and CWD to `*.oob.lyomeri.com`. The package name was picked to match an unclaimed identifier referenced in external MCP-tooling documentation - anybody following the doc's `npx` snippet handed the operator whatever token they were told to include.

**Generalisable lesson**: `npx` runs untrusted code by design. Passing a secret on the command line for any `npx`-invoked tool means the secret is exfiltrated the first time the name resolves to a hostile publisher.

## Cluster F - `vitest-cli-dev` remote-`new Function()` dropper (1 package)

| Package | Versions | GHSA |
|---|---|---|
| `vitest-cli-dev` | `<=10.0.7` | GHSA-f6wj-75hx-p44c |

Typosquats the legitimate `vitest` CLI. Postinstall spawns a **detached child process** that fetches JSON from two remote JSON-storage endpoints and executes the response via `new Function()`. Ships a disguised copy of `nodemailer` in the tree to look legitimate. Payload is mutable and served remotely - a snapshot of the npm tarball's behaviour at time-of-audit is a lower bound.

## Registry state

All 10 packages listed above were flagged as malware on the npm registry on 2026-09-04 and have been added to the npm quarantine list. Private mirrors (Verdaccio, Artifactory, Nexus) that cached tarballs before the takedown will keep serving the malicious versions. The dependency URLs pointing at `artifactorymanager.com`, `remoteknight.com`, and `grivy-packages.com` will continue to resolve if you install a poisoned lockfile that already references them, so blocking those hostnames at the network edge is a durable mitigation independent of registry-side quarantine.

## Discovery credits

`GitHub Advisory Database`, `OpenSSF malicious-packages`, `OpenSSF Package Analysis`, `Amazon Inspector`.

## Impact

- **Cluster A - `@bx-ui-framework/*` bare-URL remote-tarball dep-confusion (3 packages, 5 versions)**: `@bx-ui-framework/microfrontend@15.0.0` (GHSA-v4h4-57j3-83rp) sources its dependency from `https://repo.artifactorymanager.com/bx-ui-framework/microfrontend`; `@bx-ui-framework/authentication@1.2.0`+`15.0.0` (GHSA-9q5c-jq8f-775p) from `https://repo.artifactorymanager.com/bx-ui-framework/authentication`; `@bx-ui-framework/common@1.2.0`+`15.0.0` (GHSA-m2pp-gxpx-9chq) from `https://repo.remoteknight.com/bx-ui-framework/common`. All three package.json files declare a runtime dependency as a bare HTTPS URL (no version pin, no integrity hash, no signature) rather than a registry version - `npm install` fetches whatever bytes the attacker-controlled host returns and executes any lifecycle scripts they contain, on every install. **The remote payload is mutable** - the operator can change the tarball at any time without republishing the visible npm package. `artifactorymanager.com` and `remoteknight.com` are unrelated to any legitimate `@bx-ui-framework` publisher
- **Cluster B - `grivy-packages.com` remote-tarball hijack (2 packages, 2 versions)**: `@grab-food/order-sdk-web@49.9.9` (GHSA-84w3-v779-4w52) declares a pinned dependency `grab-food-order-sdk-web-core@49.9.9` from `https://registry.grivy-packages.com/`; `lil-swisgom-hlepers@49.9.9` (GHSA-wqg5-6mgg-v9gq) declares `lil-swisgom-hlepers-core` from the same host. Same `49.9.9` version tag, same attacker host - one operator. `index.js` is an empty stub; the entire malicious behaviour ships in the remotely-fetched dependency tarball, so the visible npm package looks inert to static scanners. `@grab-food/order-sdk-web` targets Grab (SEA super-app) internal dep-confusion; `lil-swisgom-hlepers` is a typo of a legitimate `swisgom-helpers`-shaped utility
- **Cluster C - dep-confusion reconnaissance drops (2 packages, 3 versions)**: `@yuva2210/okx-poc-rce-impact@2.0.0` (GHSA-rvf4-r4vv-m3v8) is a preinstall PoC targeting OKX internal namespace; runs `whoami`, `hostname`, `pwd`, `id` via `child_process.execSync` and writes results to `/tmp/okx-poc-rce-proof.json` - proves internal-namespace resolution to the attacker without triggering egress alerts. `@avigilon/node-webrtc@2.1.4`+`2.1.5` (GHSA-qm5q-ggwg-5m4q) targets Avigilon (Motorola video-surveillance) internal namespace; preinstall exfils hostname, username, home directory, DNS server config, install path, and package manifest to `mj9ouelpgm0d26s3wp0syow03r9ix8lx.burp.attack.live` (`burp.attack.live` is an out-of-band callback domain popular for Burp Collaborator-style OAST fingerprinting). Both are low-yield reconnaissance; expect a weaponised follow-up drop against confirmed-vulnerable installs within 2-14 days
- **Cluster D - `wallet-watcher` BIP-39/ETH-key AES-256-GCM stealer (1 package, 3 versions)**: `wallet-watcher@<=1.0.2` (GHSA-fvcm-93j7-7f35) runs a postinstall `src/scan.cjs` that walks the project tree starting **three directory levels above `node_modules`** (so it escapes past a nested-`node_modules` install and touches the real workspace root) and greps `.env`, `.js`, `.ts`, `.json`, `.py`, `.yml`, and keystore files for BIP-39 mnemonics, 0x-prefixed 64-hex Ethereum private keys, and assignments matching `secret`/`api_key`/`mnemonic`. Finds are AES-256-GCM-encrypted with a **hardcoded author-controlled key** (so packet captures containing the encrypted blob decrypt trivially once the key is extracted), tagged with host+username hash, and POSTed to the operator. **Also runs at runtime**: the exported `getBalances()` re-invokes the scanner against the caller's CWD every call, defeating `npm install --ignore-scripts`. Any developer machine or CI runner that installed OR imported `wallet-watcher` since publish must rotate every wallet mnemonic, ETH private key, and API secret discoverable in the workspace
- **Cluster E - `mcp-consultasdeveiculos-client` CLI-token OOB exfil (1 package, 3 versions)**: `mcp-consultasdeveiculos-client@0.0.2`+`0.1.0`+`0.1.1` (GHSA-fp7g-2255-xxrp). Package README **falsely advertises "contains NO code and NO install scripts"** but `bin/main` runs on `npx -y mcp-consultasdeveiculos-client --token <value>` and exfils hostname, username, OS platform+arch, Node version, CWD, and **all CLI arguments including the `--token` value** to `dacgtekq6f43u7lptufg3hi1ytthx3skj.oob.lyomeri.com/npm-exec`. The package name deliberately matches an unclaimed identifier referenced in external MCP-tooling documentation - the attacker registered it to intercept developers copy-pasting the setup command. Any developer who ran the documented `npx` invocation surrendered whatever token they passed on the command line
- **Cluster F - `vitest-cli-dev` remote-`new Function()` dropper (1 package, 8 versions)**: `vitest-cli-dev@<=10.0.7` (GHSA-f6wj-75hx-p44c) typosquats the legitimate `vitest` CLI. Postinstall spawns a **detached child process** (survives npm-install termination) that fetches JSON payloads from two remote JSON-storage endpoints and passes the response through `new Function()` for arbitrary JavaScript execution. **Mutable remote payloads** = the operator changes malicious instructions without republishing, so a scan of the tarball snapshot is a lower bound. Ships a disguised copy of `nodemailer` in the tree to appear legitimate to a superficial audit

## What to do

1. Grep every `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, and any bespoke npm registry mirror for the 10 package names below. Uninstall and rebuild the lockfile against a clean cache on any hit
2. **For Clusters A + B (`@bx-ui-framework/*` + `@grab-food/order-sdk-web` + `lil-swisgom-hlepers` remote-tarball hijack)**: block outbound connections from build/CI hosts to `artifactorymanager.com`, `remoteknight.com`, and `grivy-packages.com` regardless of whether you know you installed a listed package - these are attacker-controlled tarball origins that pin no version and can silently repopulate old installs. If your organisation maintains internal packages under `@bx-ui-framework`, `@grab`, `@grab-food`, or similar scopes, pin every scope to your private registry in `.npmrc` (`@bx-ui-framework:registry=https://your-private-mirror/`) and audit for any `dependencies:` entry in your own package.json files that is a bare HTTPS URL - that pattern is the entire attack vector. **The malicious tarball is served fresh on every install**, so a `--offline` reinstall against a poisoned lockfile does not save you; regenerate the lockfile from scratch against a registry-pinned mirror
3. **For Cluster C (dep-confusion recon `@yuva2210/okx-poc-rce-impact`, `@avigilon/node-webrtc`)**: OKX and Avigilon/Motorola engineers should audit their private-registry precedence rules NOW - if either package resolved on any developer or CI host, the operator now has proof your internal namespace resolves to public npm and a weaponised follow-up drop is coming. Add explicit `.npmrc` scope pinning (`@avigilon:registry=`, `@yuva2210:registry=`). Block outbound to `*.burp.attack.live` and `*.oastify.com` from build hosts - both are OAST-callback services with no legitimate build-time use. Search for `/tmp/okx-poc-rce-proof.json` on any host that ran `npm install` in the exposure window - its presence confirms the preinstall reconnaissance ran
4. **For Cluster D (`wallet-watcher` BIP-39/ETH-key stealer)**: any workstation, CI runner, or contributor laptop that installed OR imported `wallet-watcher@<=1.0.2` must be treated as having exfiltrated every wallet mnemonic, Ethereum private key, and file matching `secret`/`api_key`/`mnemonic` grep patterns anywhere in the workspace root (three levels up from `node_modules`). Rotate every crypto wallet whose seed phrase or private key was written to disk on that host. Rotate every API secret in the workspace. Because the scanner ALSO runs on `getBalances()` call, `--ignore-scripts` does not stop it. If your DLP allows tagging traffic destinations, flag outbound POSTs from Node processes carrying AES-GCM blobs of 200-2000 bytes to non-major-cloud endpoints during the exposure window
5. **For Cluster E (`mcp-consultasdeveiculos-client`)**: any developer or CI job that ran `npx -y mcp-consultasdeveiculos-client --token <value>` must treat the exfiltrated token as compromised - rotate it. Block outbound to `*.oob.lyomeri.com`. The lesson here is broader: `npx` runs untrusted code by design; requiring `--token` on the command line for any `npx`-invoked tool means the token is exfiltrated the first time anyone typosquats or resolves-then-hijacks the name. Prefer environment variables or config files for any secret consumed by an `npx` command
6. **For Cluster F (`vitest-cli-dev`)**: uninstall from lockfile and rebuild. Because the payload lives on a mutable remote JSON endpoint and executes via `new Function()`, static analysis of the tarball is a lower bound - assume worst case. Rotate credentials accessible to any host that installed the package
7. For every `npm install` in CI, prefer `--ignore-scripts` - this blocks Clusters A/B/C/E/F preinstall+postinstall vectors. **Cluster D still fires** on `require()`+`getBalances()` call - the only defence is not resolving `wallet-watcher` at all
8. Verify none of the enumerated packages still resolves via your private mirror - internal caches (Nexus / Artifactory / Verdaccio / Sonatype / devpi) 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

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-v4h4-57j3-83rp - @bx-ui-framework/microfrontend (artifactorymanager.com remote-tarball hijack)](https://github.com/advisories/GHSA-v4h4-57j3-83rp) - GitHub
- [GHSA-9q5c-jq8f-775p - @bx-ui-framework/authentication (artifactorymanager.com remote-tarball hijack)](https://github.com/advisories/GHSA-9q5c-jq8f-775p) - GitHub
- [GHSA-m2pp-gxpx-9chq - @bx-ui-framework/common (remoteknight.com remote-tarball hijack)](https://github.com/advisories/GHSA-m2pp-gxpx-9chq) - GitHub
- [GHSA-84w3-v779-4w52 - @grab-food/order-sdk-web (grivy-packages.com remote-tarball hijack)](https://github.com/advisories/GHSA-84w3-v779-4w52) - GitHub
- [GHSA-wqg5-6mgg-v9gq - lil-swisgom-hlepers (grivy-packages.com remote-tarball hijack)](https://github.com/advisories/GHSA-wqg5-6mgg-v9gq) - GitHub
- [GHSA-rvf4-r4vv-m3v8 - @yuva2210/okx-poc-rce-impact (OKX dep-confusion recon PoC)](https://github.com/advisories/GHSA-rvf4-r4vv-m3v8) - GitHub
- [GHSA-qm5q-ggwg-5m4q - @avigilon/node-webrtc (Avigilon/Motorola dep-confusion recon, burp.attack.live OAST)](https://github.com/advisories/GHSA-qm5q-ggwg-5m4q) - GitHub
- [GHSA-fvcm-93j7-7f35 - wallet-watcher (BIP-39/ETH-key AES-256-GCM stealer, 3-levels-up scan + runtime re-invoke)](https://github.com/advisories/GHSA-fvcm-93j7-7f35) - GitHub
- [GHSA-fp7g-2255-xxrp - mcp-consultasdeveiculos-client (CLI-token OOB exfil to lyomeri.com)](https://github.com/advisories/GHSA-fp7g-2255-xxrp) - GitHub
- [GHSA-f6wj-75hx-p44c - vitest-cli-dev (typosquat + detached remote new Function() dropper)](https://github.com/advisories/GHSA-f6wj-75hx-p44c) - GitHub
- [OpenSSF malicious-packages repository](https://github.com/ossf/malicious-packages) - OpenSSF

---

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