Skip to content

Security: Pin axios to mitigate supply chain attack#2379

Open
CChanHY wants to merge 5 commits intoMentra-Community:mainfrom
CChanHY:security/pin-axios
Open

Security: Pin axios to mitigate supply chain attack#2379
CChanHY wants to merge 5 commits intoMentra-Community:mainfrom
CChanHY:security/pin-axios

Conversation

@CChanHY
Copy link
Copy Markdown

@CChanHY CChanHY commented Mar 31, 2026

Summary

  • Pin all axios dependencies to 1.14.0 (last safe version) across 10 package.json files — removes ^ prefix to prevent npm from resolving to compromised versions
  • Add overrides in root package.json to block both compromised versions (1.14.1 and 0.30.4) from being pulled in as transitive dependencies
  • Block plain-crypto-js (the malicious payload package) from ever being installed

Context

On March 31, 2026, two malicious versions of axios were published to npm (axios@1.14.1 and axios@0.30.4) via a compromised maintainer account. The malicious versions inject a hidden dependency (plain-crypto-js@4.2.1) whose postinstall script drops a cross-platform RAT (Remote Access Trojan) targeting macOS, Windows, and Linux. The dropper then self-destructs to evade forensic detection.

References:

Affected files

All package.json files that declare axios as a dependency:

  • cloud/package.json
  • cloud/packages/cli/package.json
  • cloud/packages/cloud/package.json
  • cloud/packages/sdk/package.json
  • cloud/websites/account/package.json
  • cloud/websites/console/package.json
  • cloud/websites/debugger/package.json
  • cloud/websites/shared/package.json
  • cloud/websites/store/package.json
  • mobile/package.json
  • package.json (overrides)

Recommended follow-up

  • Run npm install --ignore-scripts to regenerate lock files with the pinned version
  • Anyone who ran npm install and received axios@1.14.1 or axios@0.30.4 should treat that machine as compromised and rotate all credentials
  • Once the axios team publishes a verified clean release, the ^ prefix can be restored

Test plan

  • Verify npm install --ignore-scripts completes without errors
  • Verify npm ls axios shows 1.14.0 across all workspaces
  • Verify plain-crypto-js is not present in node_modules

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Pinned axios to 1.14.0 across packages to enforce consistent installs.
    • Added top-level dependency resolution controls (overrides/resolutions) to lock axios and block plain-crypto-js (set to 0.0.0-blocked).
    • Standardized dependency declarations across project packages for predictable updates.
    • Introduced a trustedDependencies list to explicitly mark certain build/runtime packages as trusted.

…ios@0.30.4)

On March 31, 2026, compromised versions axios@1.14.1 and axios@0.30.4
were published to npm via a hijacked maintainer account. The malicious
versions inject a hidden dependency (plain-crypto-js@4.2.1) that drops
a cross-platform RAT via postinstall script.

This commit:
- Pins all direct axios dependencies to 1.14.0 (last known safe version)
- Adds npm overrides to block both compromised major versions
- Blocks plain-crypto-js from being installed as a transitive dependency

References:
- https://socket.dev/blog/axios-npm-package-compromised
- axios/axios#10604

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@CChanHY CChanHY requested a review from a team as a code owner March 31, 2026 10:22
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 31, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 74177775-f97a-4ef8-adde-8e8c4666407e

📥 Commits

Reviewing files that changed from the base of the PR and between 543a2f0 and dac0956.

⛔ Files ignored due to path filters (2)
  • cloud/bun.lock is excluded by !**/*.lock
  • mobile/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (1)
  • package.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json

📝 Walkthrough

Walkthrough

Pinned axios to 1.14.0 across multiple package.json files and added root-level overrides/resolutions (including blocking plain-crypto-js) plus a trustedDependencies list in the repository root package.json.

Changes

Cohort / File(s) Summary
Root Configuration
package.json
Added top-level overrides mapping axios@>=11.14.0, axios@<10.30.3, and plain-crypto-js0.0.0-blocked. Added resolutions pinning axios1.14.0 and plain-crypto-js0.0.0-blocked. Added trustedDependencies array.
Cloud Top
cloud/package.json
Changed axios from ^1.8.1 to 1.14.0.
Cloud Packages
cloud/packages/cli/package.json, cloud/packages/cloud/package.json, cloud/packages/sdk/package.json
Updated axios from caret ranges (^1.6.5, ^1.7.4, ^1.8.1) to pinned 1.14.0.
Cloud Websites
cloud/websites/account/package.json, cloud/websites/console/package.json, cloud/websites/debugger/package.json, cloud/websites/shared/package.json, cloud/websites/store/package.json
Updated axios from caret ranges (^1.4.0, ^1.8.1) to pinned 1.14.0.
Mobile
mobile/package.json
Updated axios from ^1.13.6 to pinned 1.14.0.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I nudged the pins across each JSON line,
Axios aligned, all versions fine,
Overrides stitched and a shady block set,
Trusted hops counted — no risk to fret,
I nibble the carrots of tidy design.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Security: Pin axios to mitigate supply chain attack' directly and clearly summarizes the main change: pinning axios to a specific version as a security measure against supply chain attacks.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cloud/package.json (1)

1-71: 🛠️ Refactor suggestion | 🟠 Major

Add packageManager field to enforce bun usage.

The cloud workspace root lacks a packageManager field, which creates ambiguity about which package manager should be used and may cause the root-level overrides (mentioned in PR objectives) to be ignored or applied inconsistently.

Based on coding guidelines, add:

🔧 Suggested addition to package.json
 {
   "private": true,
+  "packageManager": "bun@1.3.5",
   "workspaces": [

Choose the appropriate bun version based on your project requirements. This ensures:

  1. Consistent package manager usage across the monorepo
  2. Proper enforcement of the overrides configuration
  3. Compliance with the coding guideline to use bun for cloud packages

As per coding guidelines: "Use bun as the package manager and runtime for all project dependencies" for cloud/**/package.json files.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cloud/package.json` around lines 1 - 71, Add a top-level packageManager field
to the root package.json (near the existing "private"/"workspaces" keys) like
packageManager: "bun@<version>" to enforce Bun as the package manager and ensure
root-level overrides and Bun-specific behavior (e.g., workspace resolution and
the postinstall/build scripts) are applied consistently; pick the Bun version
that matches your CI/dev environment and update the string accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@package.json`:
- Around line 29-33: The top-level "overrides" block will be ignored by pnpm;
move the overrides into pnpm-specific configuration so pnpm enforces them.
Update package.json to nest the existing overrides object under a "pnpm" key
(e.g., add "pnpm": { "overrides": { "axios@>=1": "1.14.0", "axios@<1": "0.30.3",
"plain-crypto-js": "0.0.0-blocked" } }) or alternatively place the same
overrides in pnpm-workspace.yaml if you prefer workspace-level config; leave the
bun-specific top-level overrides in cloud/** unchanged. Ensure the symbols
"overrides", "pnpm", and the axios override entries ("axios@>=1", "axios@<1")
are present in the pnpm-recognized config.

---

Outside diff comments:
In `@cloud/package.json`:
- Around line 1-71: Add a top-level packageManager field to the root
package.json (near the existing "private"/"workspaces" keys) like
packageManager: "bun@<version>" to enforce Bun as the package manager and ensure
root-level overrides and Bun-specific behavior (e.g., workspace resolution and
the postinstall/build scripts) are applied consistently; pick the Bun version
that matches your CI/dev environment and update the string accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e8a77daf-2d6a-46de-9819-ec3d6e44638f

📥 Commits

Reviewing files that changed from the base of the PR and between 7ae24ef and fc26ada.

📒 Files selected for processing (11)
  • cloud/package.json
  • cloud/packages/cli/package.json
  • cloud/packages/cloud/package.json
  • cloud/packages/sdk/package.json
  • cloud/websites/account/package.json
  • cloud/websites/console/package.json
  • cloud/websites/debugger/package.json
  • cloud/websites/shared/package.json
  • cloud/websites/store/package.json
  • mobile/package.json
  • package.json

package.json Outdated
Comment on lines 29 to 33
"overrides": {
"axios@>=1": "1.14.0",
"axios@<1": "0.30.3",
"plain-crypto-js": "0.0.0-blocked"
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify which package manager lockfiles exist and check override syntax compatibility

echo "=== Checking for lockfiles ==="
fd -t f -d 2 'package-lock.json|pnpm-lock.yaml|yarn.lock|bun.lockb' .

echo ""
echo "=== pnpm-lock.yaml header (if exists) ==="
head -10 pnpm-lock.yaml 2>/dev/null || echo "pnpm-lock.yaml not found"

echo ""
echo "=== cloud/package.json resolutions field ==="
cat cloud/package.json 2>/dev/null | jq '.resolutions // "No resolutions field"'

echo ""
echo "=== Root package.json pnpm field ==="
cat package.json | jq '.pnpm // "No pnpm field"'

Repository: Mentra-Community/MentraOS

Length of output: 434


🏁 Script executed:

#!/bin/bash

# Check the full package.json structure
echo "=== Root package.json (relevant sections) ==="
cat package.json | jq '{scripts, overrides, pnpm, resolutions}' 2>/dev/null || cat package.json | jq -r '.overrides, .pnpm, .resolutions'

echo ""
echo "=== Cloud package.json structure ==="
cat cloud/package.json 2>/dev/null | jq '{scripts, overrides, pnpm, resolutions, workspaces}' 2>/dev/null

echo ""
echo "=== Check if bun.lockb exists ==="
ls -la bun.lockb 2>/dev/null || echo "No bun.lockb found"

echo ""
echo "=== Check for workspace-related config ==="
cat package.json | jq '.workspaces // "No workspaces field"'

Repository: Mentra-Community/MentraOS

Length of output: 3336


🌐 Web query:

pnpm overrides field top-level vs pnpm.overrides nested syntax

💡 Result:

In pnpm (version 10.x as of 2026), the overrides field is a top-level key used in pnpm-workspace.yaml at the root of the project (or workspace). It cannot be set in sub-packages and must be at the project root. Example in pnpm-workspace.yaml: overrides: foo: ^1.0.0 In package.json, pnpm-specific overrides are nested under the pnpm.overrides field (though official docs emphasize pnpm-workspace.yaml; package.json usage is common in practice, especially for non-workspace projects or root package.json). Example in root package.json: { "pnpm": { "overrides": { "foo": "^1.0.0" } } } pnpm does NOT natively support npm-style top-level overrides in package.json (e.g., "overrides": { "foo": "^1.0.0" }) due to differences in resolution algorithms. Top-level overrides is ignored by pnpm; use pnpm.overrides or pnpm-workspace.yaml instead. This is a long-standing design choice, with open issues requesting compatibility. Key differences: - pnpm-workspace.yaml: Top-level overrides (preferred for workspaces, official docs). - package.json: Nested pnpm.overrides (works in root, common in tutorials). Both achieve the same: overriding dependencies project-wide. Use root location only.

Citations:


🌐 Web query:

bun package manager resolutions vs overrides dependency resolution

💡 Result:

In Bun package manager, "overrides" and "resolutions" are equivalent mechanisms for forcing specific versions of dependencies (including metadependencies/transitive dependencies) anywhere in the dependency tree. There is no difference between them in Bun. Both are supported in package.json at the top level: - "overrides": npm-style syntax - "resolutions": Yarn-style syntax (for easier migration from Yarn) Example: { "overrides": { "bar": "~4.4.0" } } or { "resolutions": { "bar": "~4.4.0" } } Bun forces the specified version of "bar" for all occurrences, direct or nested. Limitations (as of latest docs): - Only top-level (flat) overrides/resolutions supported; nested/scoped not supported (warns and ignores). - Only read from root package.json (not workspace children). They serve the same purpose: override dependency resolution to pin versions (e.g., for security fixes), with identical behavior and syntax.

Citations:


Critical: overrides field will be ignored by pnpm.

The repository has pnpm-lock.yaml at the root (lockfileVersion 9.0), indicating pnpm is the active package manager. However, pnpm does not recognize top-level "overrides" in package.json—it requires the field nested under the "pnpm" key or defined in pnpm-workspace.yaml.

As a result, transitive dependencies pulling in compromised axios versions won't be blocked by pnpm. The field will have no effect on dependency resolution in pnpm workspaces.

Note: bun (used in cloud/**) supports the current "overrides" syntax at the top level, so no changes are needed there. The issue is pnpm-specific.

🔒 Proposed fix for pnpm compatibility
   "scripts": {
     "prepare": "husky",
     "generate-licenses": "bun docs/generate-licenses.ts"
   },
-  "overrides": {
-    "axios@>=1": "1.14.0",
-    "axios@<1": "0.30.3",
-    "plain-crypto-js": "0.0.0-blocked"
+  "pnpm": {
+    "overrides": {
+      "axios@>=1": "1.14.0",
+      "axios@<1": "0.30.3",
+      "plain-crypto-js": "0.0.0-blocked"
+    }
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"overrides": {
"axios@>=1": "1.14.0",
"axios@<1": "0.30.3",
"plain-crypto-js": "0.0.0-blocked"
}
"pnpm": {
"overrides": {
"axios@>=1": "1.14.0",
"axios@<1": "0.30.3",
"plain-crypto-js": "0.0.0-blocked"
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` around lines 29 - 33, The top-level "overrides" block will be
ignored by pnpm; move the overrides into pnpm-specific configuration so pnpm
enforces them. Update package.json to nest the existing overrides object under a
"pnpm" key (e.g., add "pnpm": { "overrides": { "axios@>=1": "1.14.0",
"axios@<1": "0.30.3", "plain-crypto-js": "0.0.0-blocked" } }) or alternatively
place the same overrides in pnpm-workspace.yaml if you prefer workspace-level
config; leave the bun-specific top-level overrides in cloud/** unchanged. Ensure
the symbols "overrides", "pnpm", and the axios override entries ("axios@>=1",
"axios@<1") are present in the pnpm-recognized config.

Note: Sub-project lock files (cloud/websites/*/package-lock.json) use
bun workspaces and need `bun install --ignore-scripts` to update.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@CChanHY
Copy link
Copy Markdown
Author

CChanHY commented Mar 31, 2026

Update: Added root package-lock.json with the pinned axios version.

The sub-project lock files (cloud/websites/*/package-lock.json) use bun workspaces and need to be updated with bun install --ignore-scripts by someone with bun installed.

Collin Chan and others added 3 commits March 31, 2026 12:34
Bun and Yarn don't support npm's overrides field — they use
resolutions instead. This ensures the axios pin is enforced
regardless of which package manager is used.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ran bun install --ignore-scripts to regenerate lock files with
axios pinned to 1.14.0 across all workspaces.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bun blocks postinstall scripts by default. This explicitly allowlists
only the packages that legitimately need lifecycle scripts (native
modules, build tools, etc.), blocking any future supply chain attacks
that use postinstall as an attack vector.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant