| name | axios-security-check |
| description | Use this skill when the user wants to check if their system is affected by the axios npm supply chain attack (March 31, 2026), scan for malicious axios versions (1.14.1, 0.30.4), check for malware artifacts, or audit package manager security settings (pnpm, npm, bun, yarn) for protections against supply chain attacks. Trigger on phrases like "axios vulnerability", "axios supply chain", "check if affected by axios", "scan for axios malware", or "package manager security audit".
|
Axios Supply Chain Attack — Security Check
Attack summary: On March 31, 2026, axios versions 1.14.1 and 0.30.4 were published via a compromised maintainer account. They silently injected plain-crypto-js@4.2.1 as a dependency, which ran a postinstall script deploying a cross-platform Remote Access Trojan (RAT). Both versions were removed by 03:29 UTC but may remain in local caches or lockfiles.
Run all four phases below and produce the report at the end.
Phase 1: Vulnerability Scan
Search for malicious axios versions in package manifests, lockfiles, and global caches.
Malicious versions: 1.14.1 and 0.30.4
1a. Project files under ~
Search for lockfiles and package.json files (limit depth to avoid excessive crawling):
find ~ -maxdepth 8 \
-not \( -path '*/.git/*' -o -path '*/node_modules/*/node_modules/*' \) \
-name "package.json" \
-exec grep -l '"axios"' {} \;
For each match, check if axios is pinned to 1.14.1 or 0.30.4:
grep -E '"axios":\s*"[^"]*1\.14\.1|[^"]*0\.30\.4"' <path>/package.json
Search lockfiles for the malicious versions:
grep -r --include="package-lock.json" --include="yarn.lock" \
--include="pnpm-lock.yaml" --include="bun.lock" \
-l "axios" ~ 2>/dev/null | head -50
For each lockfile found:
grep -A2 '"axios"' <lockfile> | grep -E "1\.14\.1|0\.30\.4"
1b. Global caches
Check global package manager caches for cached malicious tarballs:
find ~/.npm/_cacache -name "*.json" 2>/dev/null | xargs grep -l '"axios"' 2>/dev/null | \
xargs grep -l '"1.14.1"\|"0.30.4"' 2>/dev/null
find ~/Library/pnpm/store -maxdepth 6 -name "package.json" 2>/dev/null | \
xargs grep -l '"axios"' 2>/dev/null | \
xargs grep -l '"1.14.1"\|"0.30.4"' 2>/dev/null
find ~/.local/share/pnpm/store -maxdepth 6 -name "package.json" 2>/dev/null | \
xargs grep -l '"axios"' 2>/dev/null | \
xargs grep -l '"1.14.1"\|"0.30.4"' 2>/dev/null
find ~/.bun/install/cache -maxdepth 6 -name "package.json" 2>/dev/null | \
xargs grep -l '"axios"' 2>/dev/null | \
xargs grep -l '"1.14.1"\|"0.30.4"' 2>/dev/null
Phase 2: Malware Artifact Check
2a. plain-crypto-js presence
The malicious dependency used as the attack vector:
find ~ -maxdepth 10 -type d -name "plain-crypto-js" 2>/dev/null
Any result here means plain-crypto-js was installed — the install-time RAT dropper ran.
2b. Platform-specific RAT artifacts
Check for files dropped by the RAT dropper. These are fixed paths.
macOS:
ls -la /Library/Caches/com.apple.act.mond 2>/dev/null && echo "FOUND — potential RAT binary" || echo "Not found"
Linux:
ls -la /tmp/ld.py 2>/dev/null && echo "FOUND — potential RAT script" || echo "Not found"
Windows (if running in WSL or checking a Windows path):
ls -la /mnt/c/ProgramData/wt.exe 2>/dev/null && echo "FOUND — potential RAT binary" || echo "Not found"
2c. Active C2 connections
Check for live connections to the attacker's command-and-control server:
lsof -i @142.11.206.73 2>/dev/null || echo "No connections to C2 IP"
lsof -i 2>/dev/null | grep -i sfrclak || echo "No connections to sfrclak.com"
lsof -i :8000 2>/dev/null | grep -v "localhost\|127\.0\.0" || echo "No suspicious :8000 connections"
Phase 3: Package Manager Security Audit
Detect which package managers are installed and check their security-relevant configuration. Read global config files and project-level config/manifest files in the current directory.
3a. Detect installed package managers
which npm && npm --version
which pnpm && pnpm --version
which bun && bun --version
which yarn && yarn --version
3b. npm
Config files to read:
- Global:
~/.npmrc
- Project:
.npmrc in current directory
npm config get ignore-scripts
npm config get min-release-age
npm config get audit
| Setting | Secure value | Default | Effect |
|---|
ignore-scripts | true | false | Disables all lifecycle scripts for all packages |
min-release-age | e.g. 259200 (3 days in seconds) | unset | Refuses to install package versions published more recently than the threshold — blocks day-zero malicious publishes |
audit | true | true | Checks installed packages against known vulnerability advisories |
Note: npm has no per-package script allowlist — ignore-scripts is all-or-nothing.
3c. pnpm
Config files to read:
- Global:
~/.npmrc (pnpm reads this too) and pnpm config list
- Project:
.npmrc, pnpm-workspace.yaml
package.json → pnpm field
pnpm config get ignore-scripts 2>/dev/null
pnpm config get ignoreDepScripts 2>/dev/null
pnpm config get minimumReleaseAge 2>/dev/null
pnpm config get blockExoticSubdeps 2>/dev/null
pnpm config get onlyBuiltDependencies 2>/dev/null
pnpm config get neverBuiltDependencies 2>/dev/null
pnpm config get strictDepBuilds 2>/dev/null
pnpm config get dangerouslyAllowAllBuilds 2>/dev/null
Also read project-level files:
cat pnpm-workspace.yaml 2>/dev/null | grep -E "minimumReleaseAge|blockExoticSubdeps|onlyBuiltDependencies|allowBuilds|neverBuiltDependencies|strictDepBuilds|ignoreDepScripts|dangerouslyAllowAllBuilds"
cat package.json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps(d.get('pnpm',{}), indent=2))" 2>/dev/null
| Setting | Secure value | Default | Effect |
|---|
minimumReleaseAge | e.g. 1440 (1 day, in minutes) | 0 | Refuses packages published more recently than the threshold — blocks day-zero attacks like this one |
minimumReleaseAgeExclude | scoped list | unset | Packages exempt from the age check |
blockExoticSubdeps | true | false | Transitive deps must come from a registry; blocks git/tarball URL subdependencies injected by attackers |
ignoreDepScripts | true | false | Skips lifecycle scripts in dependencies only; project scripts still run |
ignoreScripts | true | false | Skips all lifecycle scripts (dependencies and project) |
onlyBuiltDependencies | Explicit allowlist | unset | Only listed packages may run install scripts — all others blocked |
allowBuilds | Per-package map | unset | Newer alternative to onlyBuiltDependencies; supports version constraints and explicit false entries |
neverBuiltDependencies | Blocklist of known-bad packages | unset | Explicitly prevents listed packages from running scripts |
strictDepBuilds | true | false | Install fails if any dependency has unreviewed build scripts — forces explicit approval |
dangerouslyAllowAllBuilds | false | false | Flag if this is true — it bypasses all script controls |
3d. bun
Config files to read:
- Global:
~/.bunfig.toml
- Project:
bunfig.toml
- Project
package.json → trustedDependencies field
cat ~/.bunfig.toml 2>/dev/null || echo "No global bunfig.toml"
cat bunfig.toml 2>/dev/null || echo "No project bunfig.toml"
cat package.json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps(d.get('trustedDependencies','not set'), indent=2))" 2>/dev/null
| Setting | Location | Secure value | Default | Effect |
|---|
trustedDependencies | package.json | Explicit allowlist | Top-500 npm packages auto-trusted | Only listed packages may run lifecycle scripts; any package not on this list is blocked |
[install].minimumReleaseAge | bunfig.toml | e.g. 259200 (seconds) | unset | Refuses packages newer than the threshold |
[install].lifecycle-scripts | bunfig.toml | Scoped allowlist | unset | Alternative/additional script execution control |
Note: Bun's default is more secure than npm — scripts are blocked for packages not in the built-in top-500 allowlist. An explicit trustedDependencies field in package.json overrides this and should be reviewed carefully.
3e. Yarn (Berry)
Config files to read:
- Global:
~/.yarnrc.yml
- Project:
.yarnrc.yml
cat ~/.yarnrc.yml 2>/dev/null | grep -E "enableScripts|dependenciesMeta" || echo "No global .yarnrc.yml"
cat .yarnrc.yml 2>/dev/null | grep -E "enableScripts|dependenciesMeta" || echo "No project .yarnrc.yml"
| Setting | Secure value | Default | Effect |
|---|
enableScripts | false | true | Disables all lifecycle scripts globally; re-enable per-package via dependenciesMeta |
3f. CI/CD workflow check
If .github/workflows/ exists, check install commands for hardening flags:
grep -r --include="*.yml" --include="*.yaml" \
-E "npm install|npm ci|pnpm install|bun install|yarn install" \
.github/ 2>/dev/null | head -20
Flags to look for: --ignore-scripts, npm ci (vs npm install), --frozen-lockfile.
Phase 4: Report
Produce a clean report with the following structure. Be explicit about each finding — "not found" is a valid and important result.
## Axios Supply Chain Attack — Security Report
Generated: <date>
### Vulnerability Scan
- Affected axios versions found in project files: <list paths or "None found">
- Affected axios versions found in global caches: <list or "None found">
### Malware Artifacts
- plain-crypto-js present: <Yes — <path> | No>
- macOS RAT binary (/Library/Caches/com.apple.act.mond): <Found | Not found>
- Linux RAT script (/tmp/ld.py): <Found | Not found>
- Windows RAT binary (%PROGRAMDATA%\wt.exe): <Found | Not found>
- Active C2 connections (sfrclak.com:8000 / 142.11.206.73): <Active | None detected>
### Package Manager Security Audit
For each installed package manager, report the key settings. Use "✓ set", "✗ unset", or the actual value.
**npm <version>:**
- `ignore-scripts`: <value>
- `min-release-age`: <value or "not set">
- `audit`: <value>
**pnpm <version>:**
- `minimumReleaseAge`: <value or "not set">
- `blockExoticSubdeps`: <value>
- `ignoreDepScripts`: <value>
- `onlyBuiltDependencies` / `allowBuilds`: <set with N packages | not set>
- `strictDepBuilds`: <value>
- `dangerouslyAllowAllBuilds`: <value — flag if true>
**bun <version>:**
- `trustedDependencies` in package.json: <explicit list | using defaults>
- `[install].minimumReleaseAge` in bunfig.toml: <value or "not set">
**yarn <version>:**
- `enableScripts`: <value or "not set (defaults to true)">
### Recommendations
[Prioritized list based on findings above — see guidance below]
Recommendation guidance (include relevant items only)
If compromised (artifacts found or C2 connections detected):
- Treat as full system breach — isolate immediately
- Rotate all credentials: API keys, SSH keys, cloud credentials, npm tokens, GitHub tokens
- Rebuild from a clean snapshot if possible
- Review logs for C2 traffic to
sfrclak.com:8000 / 142.11.206.73 between March 31 00:00–04:00 UTC 2026
If malicious axios version found (no artifacts):
- Remove from lockfile: downgrade to
axios@1.7.9 (last safe 1.x) or axios@0.29.0 (last safe 0.x)
- Delete
plain-crypto-js from node_modules and lockfile
- Run fresh install:
pnpm install / npm ci / bun install
For pnpm users:
For npm users:
- Set
min-release-age in .npmrc — this is the single most effective preventive control for day-zero attacks:
min-release-age=259200
(259200 seconds = 3 days; even 3600 = 1 hour would have blocked this attack)
- Add
ignore-scripts=true to .npmrc for CI environments (may break packages with legitimate build steps — test first)
- Use
npm ci instead of npm install in CI — it respects lockfiles exactly and fails on drift
- Run
npm audit --audit-level=high in CI pipelines
For bun users:
For yarn users (Berry):
- Add to
.yarnrc.yml: enableScripts: false
- Re-enable per package via
dependenciesMeta for packages with legitimate build scripts
General (all users):
- Always commit lockfiles to version control — they are the source of truth for installed versions
- Use
--frozen-lockfile / --ci flags in CI to prevent lockfile drift
- Consider Socket.dev or Snyk for continuous supply chain monitoring that catches malicious packages before they install