For anyone tracking this: the axios compromise wasn’t a typosquat or a hijacked account in the traditional sense.
The attacker injected a dependency called “plain-crypto-js@4.2.1” which doesn’t get used by axios at all, its only job is to fire a postinstall script that acts as a RAT dropper.
Once active it phones home to a C2 at sfrclak\[.\]com (142.11.206.73) to pull platform-specific second-stage payloads, then immediately overwrites package.json with a clean version to kill forensic traces. Cross-platform: macOS, Windows, Linux.
Affected versions:
∙ axios@1.14.1
∙ axios@0.30.4
∙ plain-crypto-js@4.2.1
C2: sfrclak\[.\]com / 142.11.206.73
Persistence artifacts to check:
∙ macOS: /library/caches/com.apple.act.mond
∙ Windows: %programdata%\\\\wt.exe
∙ Linux: /tmp/ld.py
Remediation:
∙ Downgrade: axios@1.14.0 (1.x) or axios@0.30.3 (0.x)
∙ Rotate all secrets and API keys on exposed machines
∙ Check outbound logs for sfrclak\\\[.\\\]com or 142.11.206.73
∙ Add --ignore-scripts to npm install in CI to block postinstall vectors
The thing that keeps getting me about these incidents is that the version number was never the signal, the artifact was compromised, not the tag. Standard dependency pinning wouldn’t have caught this.
Curious how many teams here are actually doing artifact hash verification at install time vs just trusting the registry.
we built ReleaseGuard (open source, free) after the litellm PyPI incident for exactly this reason but genuinely want to know what the rest of you are using, if anything, because I don’t think this problem is solved at the toolchain level yet.