- Ngày 31/3/2026, hai phiên bản axios (1.14.1 và 0.30.4) bị tiêm dependency độc hại plain-crypto-js, thả RAT xuyên nền tảng lên macOS/Windows/Linux.
- Chạy npm install trong 3 giờ cửa sổ là dính.
- Đây là mổ xẻ đầy đủ và hướng dẫn khắc phục.
TL;DR
Ngày 31/3/2026, tài khoản npm của maintainer jasonsaayman bị chiếm quyền. Kẻ tấn công publish hai phiên bản độc hại: axios@1.14.1 (tag latest) và axios@0.30.4 (tag legacy), cả hai inject dependency plain-crypto-js@4.2.1. Khi chạy npm install, postinstall hook tải về và chạy RAT (Remote Access Trojan) xuyên nền tảng cho macOS, Windows, Linux — beacon về C2 sfrclak[.]com:8000. Package độc sống ~3 tiếng trước khi bị gỡ. Microsoft quy trách nhiệm cho Sapphire Sleet (Bắc Triều Tiên); Google/Mandiant tracking dưới tên UNC1069 với backdoor WAVESHAPER.V2. Axios có ~100 triệu lượt tải mỗi tuần — blast radius khổng lồ.
Bị ảnh hưởng? Kiểm lockfile ngay, rotate toàn bộ secret, downgrade về axios@1.14.0 hoặc 0.30.3, và đừng tin máy đã bị — rebuild từ image sạch.
Chuyện gì đã xảy ra
Đây không phải typosquat, cũng không phải bug của axios. Kẻ tấn công có quyền publish trực tiếp trên tài khoản chính thức sau một chiến dịch social engineering tinh vi kéo dài ~2 tuần: mạo danh founder của một công ty, tạo một Slack workspace giả được branding kỹ, hẹn meeting qua MS Teams, rồi lừa maintainer cài một "update bị thiếu" — thực chất là RAT. Từ đó, token npm long-lived bị lấy cắp.
Trong vòng 39 phút (00:21 → 01:00 UTC ngày 31/3), kẻ tấn công publish hai nhánh latest và legacy song song để tối đa hóa độ phủ. Không một dòng code axios nào bị sửa. Diff nhị phân giữa axios@1.14.0 và 1.14.1 trên 86 file cho thấy chỉ duy nhất package.json thay đổi — thêm dependency mới plain-crypto-js, đồng thời script "prepare": "husky" bị bỏ đi (dấu hiệu publish thủ công, bypass release pipeline chuẩn).
Vì sao nó đáng sợ
Axios là HTTP client phổ biến nhất của JavaScript, ~100 triệu lượt tải/tuần trên nhánh 1.x và ~83 triệu trên 0.30.x. Bất kỳ project nào chạy npm install (hoặc bun install) trong cửa sổ ~3 tiếng đó đều có thể bị — mà không cần chạm vào một dòng code axios nào.
Đây là một trong những cuộc tấn công chuỗi cung ứng được chuẩn bị kỹ lưỡng nhất từng được ghi nhận nhắm vào một package top-10 npm. Kẻ tấn công pre-stage decoy plain-crypto-js@4.2.0 đúng 18 giờ trước đó để tạo lịch sử registry giả. 56 file crypto trong package ấy bit-for-bit giống hệt thư viện chính chủ crypto-js, khiến phân tích diff vô hiệu. Và khi npm install chạy, C2 callback đầu tiên xuất hiện trong 1.1 giây — trước khi npm resolve xong các dependency khác.
Chi tiết kỹ thuật
Dropper setup.js nặng 4.209 bytes, dùng hai lớp mã hóa để né static analysis:
- Layer 1: reversed Base64 (đảo chuỗi, thay
_bằng=, rồi decode). - Layer 2: XOR cipher với key
OrDeR_7077, hằng số333, index theo vị trí (7*i²%10).
Sau khi deobfuscate, dropper detect OS qua os.platform() rồi gọi về C2 sfrclak[.]com:8000 (IP 142.11.206.73, hosted trên Hostwinds). Payload tầng hai được chọn theo nền tảng, nhưng ba bản (PowerShell/Windows, C++/macOS, Python/Linux) đều implement cùng một RAT spec: beacon 60 giây, HTTP POST, body JSON Base64, User-Agent cứng mozilla/4.0 (compatible; msie 8.0; windows nt 5.1; trident/4.0) — UA IE8 trên macOS/Linux chính là signal phát hiện tốt nhất.
Google/Mandiant định danh RAT này là WAVESHAPER.V2: reconnaissance (hostname, uptime, process list), in-memory PE injection, thực thi PowerShell/shell tùy ý, enumerate file system, persistence qua %PROGRAMDATA%\system.bat + registry Run\MicrosoftUpdate trên Windows.
| Mục | Giá trị |
|---|---|
| Versions độc | axios@1.14.1, axios@0.30.4 |
| Dependency tiêm | plain-crypto-js@4.2.1 (decoy 4.2.0 publish trước 18h) |
| Versions an toàn | axios@1.14.0, axios@0.30.3 |
| C2 | sfrclak[.]com:8000 / 142.11.206.73 |
| Thời gian sống trên npm | ~2h 53m (1.14.1) & ~2h 15m (0.30.4) |
| Lần đầu C2 callback | 1.1 giây sau npm install |
| Snyk ID | SNYK-JS-AXIOS-15850650 |
| Phát hiện bởi | Socket scanner (~6 phút), StepSecurity, Elastic, cộng đồng |
Kỹ thuật chống điều tra
Sau khi launch payload tầng hai, dropper tự xóa dấu vết: xóa setup.js, xóa package.json chứa hook, rồi rename package.md (đã chuẩn bị sẵn, version 4.2.0 không có postinstall) thành package.json. Nếu bạn inspect node_modules/plain-crypto-js/ sau đó sẽ thấy... không có gì bất thường. Tệ hơn: chạy npm list plain-crypto-js sẽ báo version 4.2.0 — version "an toàn" — khiến IR team dễ kết luận nhầm là máy không bị.
Bằng chứng duy nhất còn lại là sự tồn tại của thư mục node_modules/plain-crypto-js/ — vì package này không phải dependency của bất kỳ phiên bản axios chính thức nào. Tìm thấy nó = đã bị.So với các vụ tương tự
So với chiến dịch Shai-Hulud (compromise 600+ package), Axios có blast-radius-per-package lớn hơn nhiều và mức độ tinh vi vận hành cao hơn hẳn: pre-stage, double-obfuscation, ba RAT implementation song song, anti-forensics, self-destruct. Microsoft và Google đồng thuận đây là tác phẩm của Bắc Triều Tiên — Sapphire Sleet (theo MSTIC) hoặc UNC1069 (theo GTIG), actor đã hoạt động từ 2018–2020, chủ yếu tài chính (ăn cắp ví crypto, target VC & blockchain).
UNC6780/TeamPCP — cũng NK-nexus — gần đây poison LiteLLM, Trivy, Checkmarx với SANDCLOCK credstealer. Nói cách khác: chuỗi cung ứng open-source đang là chiến trường địa chính trị.
Ai cần lo
- CI/CD pipeline không pin version chạy
npm installđịnh kỳ hoặc theo commit — đặc biệt các job chạy đêm giờ UTC trùng cửa sổ 00:21–03:29. - Developer đã chạy
npm install/npm updatetrong cửa sổ này. - Ai dùng
npx <pkg>@latest— non-deterministic, không có lockfile trace. - Project depend vào
@qqbrowser/openclaw-qbothoặc@shadanai/openclaw— exposure không phụ thuộc cửa sổ thời gian.
Theo Unit 42, victim thực tế trải dài high-tech, higher education, insurance, media, medical, retail — khắp US, châu Âu, Trung Đông, Nam Á, Úc. Dù actor chủ đích nhắm finance/crypto, RAT đã beacon từ mọi nơi.
Khắc phục & hardening
Nếu nghi ngờ bị:
- Grep lockfile (
package-lock.json,yarn.lock,bun.lock) choaxios@1.14.1,axios@0.30.4, hoặcplain-crypto-js(bất kỳ version). - Kiểm tra thư mục
node_modules/plain-crypto-js/— tồn tại = đã dính. - Đối xử như full system compromise. Đừng clean in-place — rebuild từ image sạch.
- Rotate mọi credential (từ máy sạch khác): npm token, AWS/GCP/Azure keys, SSH keys, GitHub PAT, Docker config,
.env, DB connection strings, session cookies. - Check network log outbound tới
sfrclak.comhoặc142.11.206.73:8000.
Hardening dài hạn:
- Pin exact version — bỏ
^và~:"axios": "1.14.0". - Force transitive:
"overrides": { "axios": "1.14.0" }. - Dùng
npm ci --ignore-scriptstrong CI — chặn postinstall hook từ gốc. - Bật cooldown / min-release-age: npm v11.10+
minimumReleaseAge, pnpm v10.16+ tương tự, Yarn v4.10+npmMinimalAgeGate, Dependabot cooldown. - Block DNS/proxy:
sfrclak.com,142.11.206.73. - Sandbox dev environment, vault secret (aws-vault / OS keychain), deploy EDR.
- Với maintainer high-download package: publish qua OIDC từ CI, bật 2FA bằng hardware key, không giữ long-lived token trên máy cá nhân.
Axios sẽ làm gì tiếp theo
Đội axios công bố lộ trình: wipe toàn bộ thiết bị + reset credential; chuyển hẳn sang OIDC Trusted Publisher flow (publish gắn chặt với GitHub Actions workflow qua chữ ký, không còn token long-lived); thiết lập immutable release; review tất cả GitHub Actions theo best practice; hợp tác với OpenJS Security Working Group. Publish trực tiếp từ máy cá nhân — mà vụ này đã khai thác — sẽ chấm dứt.
Bài học lớn hơn: các package top npm giờ là active target cho social engineering cấp quốc gia. Một maintainer trung thực click nhầm một update giả là đủ để lây 100 triệu máy. OIDC + publish-from-CI + hardware 2FA không còn là nice-to-have — đó là baseline mới.
Nguồn: axios post-mortem #10636, Microsoft Security, Google Threat Intelligence, Elastic Security Labs, Snyk, Unit 42, Socket, StepSecurity. Advisory chính thức: CISA Alert.


