[CRITICAL] | Active RAT | Malicious npm versions removed | Assess all systems that ran npm install during exposure window
TL;DR
Attackers compromised the npm account of the primary axios maintainer and published two malicious versions that silently install a cross-platform remote access trojan. Axios itself is not vulnerable; the attack used account takeover to inject a poisoned dependency. Malicious versions have been removed from the registry, but any environment that ran npm install during the exposure window may have an active RAT or compromised credentials.
The Situation
On 2026-03-31, an unknown threat actor compromised the npm account of jasonsaayman, the primary maintainer of axios. The attacker changed the account email to ifstap@proton[.]me and manually published two malicious versions - axios@1.14.1 at 00:21 UTC and axios@0.30.4 at 01:00 UTC - via the npm CLI, bypassing the project's GitHub Actions CI/CD pipeline entirely.
Both malicious axios versions were removed from the npm registry within hours of disclosure, but exploitation has been confirmed in the wild. Bitdefender telemetry confirms RAT execution attempts on customer systems, blocked by GravityZone. Wiz telemetry observed RAT execution in approximately 3% of environments where affected versions were present. Axios has over 100 million weekly downloads and is present in roughly 80% of cloud and code environments (Wiz). The blast radius is not theoretical.
No attribution has been established. Bitdefender Labs continues monitoring the situation.
How It's Exploited
The attack did not exploit a vulnerability in axios. Instead, it exploited the trust the JavaScript ecosystem places in the npm registry and in named maintainer accounts.
The operation was pre-staged roughly 18 hours before the malicious axios versions were published. The attack vector was a hidden dependency: the compromised axios versions included plain-crypto-js as a new package dependency - a package that axios has never used and that exists solely to execute a postinstall RAT dropper. To avoid automated trust signals, the attacker published a clean, benign version 4.2.0 first at 05:57 UTC on 2026-03-30, establishing a publication history before the malicious 4.2.1 followed at 23:59 UTC. Twenty-two minutes later, axios@1.14.1 went live. axios@0.30.4 followed 39 minutes after that - simultaneously targeting both the 1.x and 0.x release branches used across the ecosystem.
Any project using standard version ranges with a caret prefix - ^1.14.0 or ^0.30.0 - would have pulled a compromised version on its next npm install. The caret tells npm "install this version or anything newer that doesn't break compatibility" - so ^1.14.0 permits npm to automatically pull 1.14.1. This is the default behavior for most npm projects and is how the attack propagated at scale.
Once the malicious version was installed, the dropper executed silently during the npm postinstall phase, contacted C2 infrastructure at sfrclak[.]com:8000, and downloaded a platform-specific second-stage RAT - without any user interaction and without modifying axios itself. The RAT beacons to C2 every 60 seconds and supports remote shell execution, binary injection, directory browsing, process listing, and system reconnaissance. The dropper then self-deleted and replaced its own package.json with a clean version to impede forensic detection.
The credentials at risk are not limited to npm tokens. Any secret accessible to the process that ran npm install - environment variables, cloud API keys, SSH keys, CI/CD pipeline secrets - should be treated as compromised. Developer machines and CI/CD build environments are the primary exposure surface.
We assess that the operational sophistication of this attack — pre-staged clean package, dual release branches hit within 39 minutes, three platform-specific payloads pre-built, forensic self-deletion — indicates deliberate planning targeting high-value developer credentials at scale rather than opportunistic compromise.
Attack Methodology
The Dropper
Axios packages contain no malicious code, the sole change from the legitimate versions was the addition of plain-crypto-js@4.2.1 as a dependency. This package is never imported or called by axios. Its only function is executing a postinstall script, setup.js, when npm processes the package.
npm and GitHub are independent systems. Publishing to the npm registry requires only valid npm account credentials - not access to the GitHub repository. GitHub never saw the release - which is why neither malicious version appears in the repository's tag history.
Socket's automated detection flagged the malicious dropper package, plain-crypto-js@4.2.1, six minutes after it was published - at 00:05 UTC on 2026-03-31. Bitdefender telemetry recorded the first ATC detection at 00:27 UTC - six minutes after axios@1.14.1 was published - blocking execution on Windows endpoints before any public reporting had connected axios to the compromise.
The dropper uses two layers of obfuscation to evade static analysis: reversed Base64 encoding with padding character substitution, and an XOR cipher with key OrDeR_7077 and constant 333. Sensitive modules - fs, os, execSync - are loaded dynamically at runtime rather than declared as static imports. This is why the malicious package was not flagged by signature-based scanners during the six-minute window before Socket's automated detection.
At execution, the dropper detects the host platform, then:
- Locates system utilities dynamically (on Windows, runs where powershell rather than using a hardcoded path)
- Stages platform-specific files in temp directories using the fixed campaign identifier 6202033
- Contacts sfrclak[.]com:8000 to download the platform-specific second-stage payload, disguising the request as npm registry traffic (packages.npm.org/product1) using an IE8 user agent string
- Executes the payload
- Self-deletes and replaces its own package.json with a clean version
Platform Specific Payloads
Windows
The dropper copies the system PowerShell binary to %PROGRAMDATA%\wt.exe, then writes two files to the temp directory: 6202033.vbs (a VBScript launcher) and 6202033.ps1 (the PowerShell RAT payload). The VBScript launcher executes wt.exe with -w hidden -ep bypass, concealing the console window and bypassing execution policy restrictions.
wt.exe is a copy of the legitimate PowerShell binary - it carries genuine Microsoft metadata and loads legitimate PowerShell DLLs. The binary itself is not malicious and will not trigger file-based detection. The detection signal is entirely behavioral: a PowerShell binary executing from %PROGRAMDATA% with hidden window flags, bypassing execution policy, and reaching out to a non-standard port.
The PS1 payload establishes persistence by writing a hidden batch file to %PROGRAMDATA%\system.bat and adding a registry key at HKCU\Software\Microsoft\Windows\CurrentVersion\Run\MicrosoftUpdate pointing to it. On each execution, system.bat fetches the PS1 payload directly from C2 and executes it in memory via [scriptblock]::Create() - no payload file is written to disk after the initial drop. The RAT survives reboots on Windows.
On first C2 contact, the RAT enumerates Documents, Desktop, OneDrive, AppData\Roaming, and all drive roots, sending a full directory listing to the operator before the beacon loop begins. Each subsequent beacon transmits hostname, username, OS version, timezone, install date, boot time, current time, model, CPU type, and a full running process list. The operator receives three command types: peinject (in-memory PE injection via .NET reflection, requiring SeDebugPrivilege), runscript (remote PowerShell execution), and kill (graceful self-termination).
LINUX
A Python RAT is downloaded to /tmp/ld.py and executed via nohup, detaching it from the npm process tree. Stage-3 binaries are written to /tmp/.<random> (hidden).
The Linux RAT has no built-in persistence mechanism - it runs until the next reboot. Linux systems that have rebooted since the exposure window no longer have an active RAT. Credentials remain compromised regardless of reboot status.
What to Do Now
The steps below expand on the immediate actions summarized in the TL;DR.
1. Identify Exposure
Check whether your environment installed axios@1.14.1 or axios@0.30.4 during the exposure window.
npm list axios
The exposure window ran from 00:21 UTC to approximately 03:15 UTC on 2026-03-31 - roughly three hours. If either version appears in your dependency tree, treat the system as compromised.
Check for the dropper directory:
ls node_modules/plain-crypto-js/
Presence of this directory confirms the dropper executed, even if the malicious files have been replaced by the dropper's own self-deletion routine.
Check for RAT artifacts and persistence mechanisms by platform:
- macOS: /Library/Caches/com.apple.act.mond
- Windows: %PROGRAMDATA%\wt.exe, %PROGRAMDATA%\system.bat, registry key HKCU\Software\Microsoft\Windows\CurrentVersion\Run\MicrosoftUpdate
- Linux: /tmp/ld.py, /tmp/.<random> (hidden files)
On Windows, checking for wt.exe alone is not sufficient. A system that has rebooted since compromise will have no active RAT process, but system.bat and the registry key will persist and re-establish C2 contact on next login. Check for both.
2. Assess for Prior Compromise
If the dropper executed, assume full credential compromise. Check for outbound connections to sfrclak[.]com:8000 and 142.11.206[.]73 in network logs, proxy logs, and endpoint telemetry.
If a RAT artifact is present, rebuild from a known-good state rather than attempting in-place remediation.
Rotate immediately:
- npm access tokens
- Cloud API keys (AWS, GCP, Azure) accessible to the build environment
- CI/CD pipeline secrets (GitHub Actions, GitLab CI, Jenkins, etc.)
- SSH keys accessible to the affected process
- Any environment variables containing secrets present during npm install
3. Monitor Outgoing
Search endpoint and network telemetry for the IOCs listed below. If GravityZone Network Protection is active, review blocked connection logs for C2 callbacks - a block confirms attempted RAT activity.
Indicators of Compromise
| Type | Indicator | Context |
| Package | axios@1.14.1 | Malicious version - do not install |
| Package | axios@0.30.4 | Malicious version - do not install |
| Package | plain-crypto-js@4.2.1 | RAT dropper - injected as hidden dependency |
| Domain | sfrclak[.]com | C2 server |
| IP | 142.11.206[.]73 | C2 IP address |
| Network | sfrclak[.]com:8000 | C2 endpoint - RAT beacons every 60 seconds |
| File | /Library/Caches/com.apple.act.mond | RAT binary on macOS |
| File | %PROGRAMDATA%\wt.exe | Renamed PowerShell.exe on Windows - detection is behavioral |
| File | %PROGRAMDATA%\system.bat | Persistence launcher on Windows |
| File | %TEMP%\6202033.ps1 | PowerShell RAT payload on Windows |
| File | %TEMP%\6202033.vbs | VBScript launcher on Windows |
| File | /tmp/ld.py | Python RAT on Linux |
| Directory | node_modules/plain-crypto-js/ | Presence confirms dropper executed |
| Registry | HKCU\Software\Microsoft\Windows\CurrentVersion\Run\MicrosoftUpdate | Persistence registry key on Windows |
| Type | Indicator | Context |
| Hash | fcb81618bb15edfdedfb638b4c08a2af9cac9ecfa551af135a8402bf980375cf | Linux second-stage RAT (ld.py) - source: SafeDep |
| Hash | 92ff08773995ebc8d55ec4b8e1a225d0d1e51efa4ef88b8849d0071230c9645a | macOS second-stage RAT binary - source: Mend.io |
| Hash | ed8560c1ac7ceb6983ba995124d5917dc1a00288912387a6389296637d5f815c | 6202033.ps1 - Windows PowerShell RAT payload |
| Hash | e10b1fa84f1d6481625f741b69892780140d4e0e7769e7491e5f4d894c2e0e09 | 6202033.vbs - VBScript launcher |
| Hash | f7d335205b8d7b20208fb3ef93ee6dc817905dc3ae0c10a0b164f4e7d07121cd | system.bat - Windows persistence launcher |
| Account | jasonsaayman | Compromised npm maintainer account |
| Account | ifstap@proton[.]me | Attacker-controlled account used to hijack maintainer |
GravityZone Coverage
- Advanced Threat Control (ATC): ATC detected and blocked this attack on Windows with no prior knowledge of the threat - no rule updates, no signature changes, no threat intelligence. The first detection in Bitdefender telemetry occurred six minutes after axios@1.14.1 was published and before any public reporting had connected axios to the compromise. ATC blocked execution when wt.exe - a renamed PowerShell binary - attempted to execute the PowerShell payload from C2, preventing the RAT from being fully deployed on protected Windows systems. Process Protection on TechZone
- Bitdefender MDR: Bitdefender MDR is actively threat hunting across all MDR customer environments in coordination with Bitdefender Labs. MDR customers will be contacted directly if indicators associated with this campaign are identified
in their environment. To ensure your environment is included in targeted advisories and proactive hunting, keep your software inventory current in GravityZone - MDR uses inventory data to scope hunting campaigns and deliver targeted notifications. Bitdefender MDR on TechZone.
- GravityZone EDR: EDR detected the attack across all three platforms via behavioral signals. EDR/XDR/MDR on TechZone
- On Windows: PowershellExecutedFromUnusualLocation and PossibleProcessMasquerading flagged wt.exe running from %PROGRAMDATA% with hidden window and execution policy bypass; FileDownload.Curl flagged the C2 download.
- On Linux: EDR.RemoteFileCopy, EDR.RemoteScriptCopy, and EDR.Node.UnusualChildProcessTree flagged the curl download and node spawning nohup/python3.
- On macOS: EDR.RemoteFileCopy, EDR.FilePermissionsModification, and EDR.UntrustedTreeShell flagged the full execution chain.
- GravityZone Proactive Hardening and Attack Surface Reduction (PHASR): Beta detections for PHASR triggered across macOS, Windows, and Linux during this incident via PHASR.Curl.Silent, confirming that the production rule - currently in beta - would have prevented this attack on all three platforms. The PHASR rule for this pattern is expected to reach production in an upcoming release.
PHASR on TechZone
- Network Protection: Network artefacts are confirmed in GravityZone threat intelligence feeds and blocked at the network level. Note that this detection was added after the exposure window - Network Protection limits ongoing C2 activity for systems that remain compromised but would not prevent initial compromise during the attack. Organizations with Network Protection active should review blocked connection logs for evidence of attempted C2 callbacks.
Network Protection on TechZone
- Antimalware signatures: GravityZone antimalware signatures have been updated with known IOCs from this attack. Signature-based detection is a secondary layer added for performance - behavioral modules ATC and PHASR were the active defenders and operated without signatures or prior threat intelligence. Antimalware on TechZone


