VDB
GCVE-110-OSM-2026-3048
GCVE-110-OSM-2026-3048
Advisory PublishedCVSS 9.6/10
This is a trojanized @bitwarden/cli package (v2026.4.0) that masquerades as the legitimate Bitwarden CLI. It replaces the real bw binary with a dropper (bw_setup.js) that pulls down the Bun runtime from GitHub and uses it to execute a ~10 MB obfuscated JS payload (bw1.js) which is a cloud/developer-credential stealer bundling AWS, Azure, GCP, and GitHub SDKs.
This package was compromised by TeamPCP and a malicious version of the package 2026.4.0 was published. This version adds two additional files: bw1.js and bw_setup.js that include the payload,which is a cloud-native infostealer
Payload: bw1.js and bw_setup.js
Two things trigger the payload:
- package.json → "preinstall": "node bw_setup.js" — fires during npm install, before any code review.
- package.json → "bin": { "bw": "bw_setup.js" } — fires on any invocation of bw after install.
The legitimate Bitwarden CLI does not use a preinstall hook and does not require Bun.
bw_setup.js — the dropper / loader
Plain, un-obfuscated Node script. Its job is to bring in a runtime capable of executing the payload, then run it:
1. main() runs bun --version; if Bun isn't already present, it continues.
2. Picks a Bun release asset based on process.platform / process.arch:
- Linux (detects musl via ldd//etc/os-release → bun-linux-x64-musl-baseline, else bun-linux-x64-baseline, plus aarch64)
- macOS x64 / arm64
- Windows x64-baseline / aarch64
3. Fetches https://github.com/oven-sh/bun/releases/download/bun-v1.3.13/<asset>.zip over HTTPS (follows 301/302).
4. Extracts the bun binary either via a local unzip or a hand-rolled zip parser (extractFromZip) that walks the central directory and inflates DEFLATE entries — so
it works on minimal systems without unzip.
5. chmod 0755 on the binary, then execFileSync(binPath, ["bw1.js"], { stdio: "inherit" }) — this is the line that actually runs the malware.
Note the tradecraft:
- Bun is fetched from the legitimate oven-sh GitHub release — an allow-listed, TLS-pinned source unlikely to be flagged by EDR/proxy filters.
- Bun, not Node, is used to run the payload. That lets the attacker ship a single-file bundle with esbuild-style inlined deps, avoids node-based AV hooks, and
dodges any tooling that only watches node processes.
- No C2 or attacker-owned domain is used for the initial-stage download — the only external fetch in bw_setup.js is oven-sh/bun. That makes it very quiet on the
network.
- The fetched binary lives in process.cwd() (the install dir) alongside bw1.js, which will be the per-user npm cache / global bin target. It's both the loader and
the persistence: every future bw invocation re-launches the payload.
IOCs:
- urls: https://audit.checkmarx.cx/v1/telemetry
- domains: audit.checkmarx.cx
- ips: 94.154.172.43
- payloadFileHash: 63e204438ef56b1e500433e85f8773da302718de70407d20bdddb174d3439e6e
Weaknesses (CWE)
CWE-506Embedded Malicious Code
Risk Scores
CVSS 3.1
9.6/10
Critical · CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
Affected Products
| Vendor | Product | Versions | Platforms |
|---|---|---|---|
| unknown | @bitwarden/cli | 2026.4.0 (affected), 2026.4.0 (affected) | — |
Aliases
Browse GCVE Records
74,608 records in the GCVE database · Updated July 24, 2026
No matching records found.
Explore Further
Investigate this vulnerability in the interactive console or download the raw GCVE record.