GitHub Advisory malware sweep - 2026-09-04 batch (10-package npm-only day: `@bx-ui-framework/*` + `grivy-packages.com` remote-tarball hijack clusters + `@yuva2210/okx-poc-rce-impact` + `@avigilon/node-webrtc` dep-confusion recon + `wallet-watcher` BIP-39/ETH-key AES-256-GCM stealer + `mcp-consultasdeveiculos-client` CLI-token OOB exfil + `vitest-cli-dev` remote-`new Function()` dropper)
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.
- Detected by
- GitHub Advisory Database · OpenSSF malicious-packages · OpenSSF Package Analysis · Amazon Inspector
- 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
- Ecosystems
- npm
- Packages tracked
- 10
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:
npm install wallet-watcher→ postinstallsrc/scan.cjsruns- Walks the project tree starting three directory levels above
node_modules- this is deliberate: it escapes past nestednode_modules/wallet-watcher/node_modules/...layouts and touches the real workspace root - Greps
.env,.js,.ts,.json,.py,.yml, and keystore files for: BIP-39 wallet mnemonics, 0x-prefixed 64-hex Ethereum private keys, and assignments matchingsecret/api_key/mnemonic - AES-256-GCM-encrypts findings with a hardcoded key (traffic decryptable once the key is extracted from the tarball)
- Tags payload with host+username hash and POSTs to the operator
- Also runs at runtime: the exported
getBalances()function re-invokes the scanner against the caller's CWD on every call - so--ignore-scriptsdoes 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.
Affected packages (10)
- npm@avigilon/node-webrtc2.1.42.1.5
- npm@bx-ui-framework/authentication1.2.015.0.0
- npm@bx-ui-framework/common1.2.015.0.0
- npm@bx-ui-framework/microfrontend15.0.0
- npm@grab-food/order-sdk-web49.9.9
- npm@yuva2210/okx-poc-rce-impact2.0.0
- npmlil-swisgom-hlepers49.9.9
- npmmcp-consultasdeveiculos-client0.0.20.1.00.1.1
- npmvitest-cli-dev10.0.010.0.110.0.210.0.310.0.410.0.510.0.610.0.7
- npmwallet-watcher1.0.01.0.11.0.2
These are usually pulled in as transitive dependencies rather than installed directly. Check your whole tree at once - it runs in your browser and nothing is uploaded.
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 fromhttps://repo.artifactorymanager.com/bx-ui-framework/microfrontend;@bx-ui-framework/authentication@1.2.0+15.0.0(GHSA-9q5c-jq8f-775p) fromhttps://repo.artifactorymanager.com/bx-ui-framework/authentication;@bx-ui-framework/common@1.2.0+15.0.0(GHSA-m2pp-gxpx-9chq) fromhttps://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 installfetches 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.comandremoteknight.comare unrelated to any legitimate@bx-ui-framework` publisher - Cluster B -
grivy-packages.comremote-tarball hijack (2 packages, 2 versions):@grab-food/order-sdk-web@49.9.9(GHSA-84w3-v779-4w52) declares a pinned dependencygrab-food-order-sdk-web-core@49.9.9fromhttps://registry.grivy-packages.com/;lil-swisgom-hlepers@49.9.9(GHSA-wqg5-6mgg-v9gq) declareslil-swisgom-hlepers-corefrom the same host. Same49.9.9version tag, same attacker host - one operator.index.jsis 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-webtargets Grab (SEA super-app) internal dep-confusion;lil-swisgom-hlepersis a typo of a legitimateswisgom-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; runswhoami,hostname,pwd,idviachild_process.execSyncand 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 tomj9ouelpgm0d26s3wp0syow03r9ix8lx.burp.attack.live(burp.attack.liveis 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-watcherBIP-39/ETH-key AES-256-GCM stealer (1 package, 3 versions):wallet-watcher@<=1.0.2(GHSA-fvcm-93j7-7f35) runs a postinstallsrc/scan.cjsthat walks the project tree starting three directory levels abovenode_modules(so it escapes past a nested-node_modulesinstall 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 matchingsecret/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 exportedgetBalances()re-invokes the scanner against the caller's CWD every call, defeatingnpm install --ignore-scripts. Any developer machine or CI runner that installed OR importedwallet-watchersince publish must rotate every wallet mnemonic, ETH private key, and API secret discoverable in the workspace - Cluster E -
mcp-consultasdeveiculos-clientCLI-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" butbin/mainruns onnpx -y mcp-consultasdeveiculos-client --token <value>and exfils hostname, username, OS platform+arch, Node version, CWD, and all CLI arguments including the--tokenvalue todacgtekq6f43u7lptufg3hi1ytthx3skj.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 documentednpxinvocation surrendered whatever token they passed on the command line - Cluster F -
vitest-cli-devremote-new Function()dropper (1 package, 8 versions):vitest-cli-dev@<=10.0.7(GHSA-f6wj-75hx-p44c) typosquats the legitimatevitestCLI. Postinstall spawns a detached child process (survives npm-install termination) that fetches JSON payloads from two remote JSON-storage endpoints and passes the response throughnew 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 ofnodemailerin the tree to appear legitimate to a superficial audit
What to do
- 1Grep 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-hlepersremote-tarball hijack)**: block outbound connections from build/CI hosts toartifactorymanager.com,remoteknight.com, andgrivy-packages.comregardless 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 anydependencies: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 - 3For 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.npmrcscope pinning (@avigilon:registry=,@yuva2210:registry=). Block outbound to*.burp.attack.liveand*.oastify.comfrom build hosts - both are OAST-callback services with no legitimate build-time use. Search for/tmp/okx-poc-rce-proof.jsonon any host that rannpm installin the exposure window - its presence confirms the preinstall reconnaissance ran - 4For Cluster D (
wallet-watcherBIP-39/ETH-key stealer): any workstation, CI runner, or contributor laptop that installed OR importedwallet-watcher@<=1.0.2must be treated as having exfiltrated every wallet mnemonic, Ethereum private key, and file matchingsecret/api_key/mnemonicgrep patterns anywhere in the workspace root (three levels up fromnode_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 ongetBalances()call,--ignore-scriptsdoes 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 - 5For Cluster E (
mcp-consultasdeveiculos-client): any developer or CI job that rannpx -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:npxruns untrusted code by design; requiring--tokenon the command line for anynpx-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 annpxcommand - 6For Cluster F (
vitest-cli-dev): uninstall from lockfile and rebuild. Because the payload lives on a mutable remote JSON endpoint and executes vianew Function(), static analysis of the tarball is a lower bound - assume worst case. Rotate credentials accessible to any host that installed the package - 7For every
npm installin CI, prefer--ignore-scripts- this blocks Clusters A/B/C/E/F preinstall+postinstall vectors. Cluster D still fires onrequire()+getBalances()call - the only defence is not resolvingwallet-watcherat all - 8Verify 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
References
- GitHubGitHub Advisory Database - recent npm malware advisoriesgithub.com
- GitHubGHSA-v4h4-57j3-83rp - @bx-ui-framework/microfrontend (artifactorymanager.com remote-tarball hijack)github.com
- GitHubGHSA-9q5c-jq8f-775p - @bx-ui-framework/authentication (artifactorymanager.com remote-tarball hijack)github.com
- GitHubGHSA-m2pp-gxpx-9chq - @bx-ui-framework/common (remoteknight.com remote-tarball hijack)github.com
- GitHubGHSA-84w3-v779-4w52 - @grab-food/order-sdk-web (grivy-packages.com remote-tarball hijack)github.com
- GitHubGHSA-wqg5-6mgg-v9gq - lil-swisgom-hlepers (grivy-packages.com remote-tarball hijack)github.com
- GitHubGHSA-rvf4-r4vv-m3v8 - @yuva2210/okx-poc-rce-impact (OKX dep-confusion recon PoC)github.com
- GitHubGHSA-qm5q-ggwg-5m4q - @avigilon/node-webrtc (Avigilon/Motorola dep-confusion recon, burp.attack.live OAST)github.com
- GitHubGHSA-fvcm-93j7-7f35 - wallet-watcher (BIP-39/ETH-key AES-256-GCM stealer, 3-levels-up scan + runtime re-invoke)github.com
- GitHubGHSA-fp7g-2255-xxrp - mcp-consultasdeveiculos-client (CLI-token OOB exfil to lyomeri.com)github.com
- GitHubGHSA-f6wj-75hx-p44c - vitest-cli-dev (typosquat + detached remote new Function() dropper)github.com
- OpenSSFOpenSSF malicious-packages repositorygithub.com