Skip to content

How to Remediate After Installing the Compromised Axios 1.14.1 NPM Package

I was vibe coding today, installed axios, and then saw the news: axios 1.14.1 had been compromised. The malicious version was pulling environment variables and exfiltrating them to attacker-controlled servers.

My heart sank. I had AWS keys, database passwords, and API tokens in my environment.

The Immediate Panic

When I checked my installed version:

check-axios-version.sh
npm list axios
# [email protected] /home/user/projects/my-project
# └── [email protected]

Version 1.14.1. The compromised one.

I immediately wondered: what secrets had I exposed? What had the attackers already done with my credentials?

What I Did First (And Why It Was Wrong)

My first instinct was to rotate my AWS keys immediately. I went to the AWS console, created new keys, and updated my local environment.

Then I realized: I still had axios 1.14.1 installed. If I ran any npm scripts, the new keys would be stolen again.

Lesson: Rollback first, rotate second.

The Correct Order

I should have done this:

remediation-order.txt
Phase 1: Rollback axios to safe version (immediate)
Phase 2: Clean npm cache (prevents reinstall)
Phase 3: Verify package integrity
Phase 4: Rotate ALL credentials (comprehensive)
Phase 5: Check CI/CD pipelines (blast radius)

Step 1: Rollback Axios

rollback-axios.sh
# Pin to exact safe version
npm install [email protected] --save-exact
# Or for yarn users
yarn add [email protected] --exact
# Or for pnpm
pnpm add [email protected] --save-exact

The --save-exact flag is important. It prevents npm from installing a newer version next time someone runs npm install.

Step 2: Clean Install

After rollback, I needed to make sure the compromised package wasn’t hiding in my cache:

clean-install.sh
# Delete node_modules and lockfile
rm -rf node_modules package-lock.json
# Clean npm cache thoroughly
npm cache clean --force
# Fresh install with integrity verification
npm ci

npm ci (clean install) is better than npm install here because it strictly follows the lockfile and verifies integrity.

Step 3: Verify Integrity

verify-package.sh
# Check axios is now safe
npm list axios
# Should show: [email protected]
# Run security audit
npm audit
# View axios version history
npm view axios versions --json | grep "1.14"
# Shows: "1.14.0" but NOT "1.14.1"

npm had already pulled the malicious 1.14.1 from the registry, so you won’t find it in the version list anymore.

Step 4: Credential Rotation (The Painful Part)

This is where it gets tedious. I had to rotate everything:

credential-rotation-checklist.txt
Critical (Do First):
- AWS Access Keys (all regions, all accounts)
- Database passwords (production, staging, dev)
- API keys for payment services (Stripe, PayPal, etc.)
- OAuth tokens and client secrets
- JWT signing keys
High Priority:
- CI/CD environment variables (GitHub Actions, GitLab CI)
- Container registry credentials
- Cloud provider service account keys
- Third-party API keys (SendGrid, Twilio, etc.)
Medium Priority:
- Internal service tokens
- Monitoring/logging API keys
- Development environment secrets

The key insight: attackers may hold credentials for weeks before using them. Even if you rotate today, they might have already extracted your secrets hours ago. You need to assume breach.

AWS Key Rotation

For AWS, I used this approach:

rotate-aws-keys.sh
# List current keys
aws iam list-access-keys --user-name $AWS_USERNAME
# Create new key
aws iam create-access-key --user-name $AWS_USERNAME \
--output json > new-keys.json
# Extract credentials
NEW_ACCESS_KEY=$(cat new-keys.json | jq -r '.AccessKey.AccessKeyId')
NEW_SECRET_KEY=$(cat new-keys.json | jq -r '.AccessKey.SecretAccessKey')
# Update your apps/secret manager with these new keys
# Then delete old keys
aws iam delete-access-key \
--user-name $AWS_USERNAME \
--access-key-id OLD_KEY_ID

Important: Update all consuming services before deleting the old key. I broke a production deployment by deleting keys too fast.

What About CI/CD?

This is the hidden danger. If your CI/CD pipeline ran during the compromise window, those environment variables were exposed too.

I checked my GitHub Actions runs:

check-ci-history.sh
# Find commits during compromise window
git log --since="2024-10-13" --until="2024-10-14" --oneline
# Check what ran in CI
# Go to GitHub Actions page and review all runs during that window

Any secrets used in those runs need rotation. This includes:

  • GITHUB_TOKEN (usually auto-generated, but check)
  • Any custom secrets you defined
  • Any environment variables passed to jobs

Common Mistakes I Made (And Fixed)

  1. Rotating credentials before rollback — The new credentials would be stolen immediately if axios 1.14.1 was still installed.

  2. Only rotating production credentials — Dev and staging credentials are equally valuable. Attackers can use dev access to learn your architecture before attacking production.

  3. Forgetting CI/CD secrets — GitHub Actions secrets, GitLab CI variables, Docker Hub tokens — all need rotation.

  4. Not checking historical deployments — If CI/CD ran during the compromise window, those secrets were exposed.

  5. Trusting npm install — I should have used npm ci for clean, verified installs.

Why This Matters for Supply Chain Security

The axios compromise is a reminder: even widely-used, trusted packages can be compromised. axios has 30+ million weekly downloads. When it gets hit, thousands of developers are affected.

Here’s what the attack looked like conceptually:

attack-flow.txt
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ npm install │ ──▶ │ axios 1.14.1 │ ──▶ │ postinstall.js │
│ (developer) │ │ (compromised) │ │ (malicious) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
┌─────────────────┐
│ Read env vars │
│ (AWS_KEY, etc) │
└─────────────────┘
┌─────────────────┐
│ HTTP POST to │
│ attacker server│
└─────────────────┘

The malicious code ran during npm install — no interaction required from the developer. Just installing the package triggered the exfiltration.

Prevention for Future

After this incident, I changed my workflow:

  1. Pin exact versions — Use --save-exact to prevent floating versions
  2. Commit lockfilespackage-lock.json is your safety net
  3. Use npm ci — Not npm install for production deployments
  4. Run npm audit in CI — Block builds with known vulnerabilities
  5. Minimal CI permissions — Use short-lived tokens, not persistent secrets
  6. Secret scanning — Tools like GitGuardian detect exposed credentials in git history

Summary

In this post, I showed my remediation process after discovering axios 1.14.1 was installed. The key lessons:

  1. Rollback first, rotate second — Don’t let new credentials get stolen
  2. Clean everything — Cache, node_modules, lockfiles
  3. Rotate comprehensively — All environments, all services, all CI/CD secrets
  4. Assume breach — Attackers may already have your credentials

The axios compromise scared me, but it also taught me that supply chain security is not optional. When a package with 30 million weekly downloads gets hit, you need a response plan ready.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments