Axios Bị Chiếm Quyền Trên npm — RAT Ẩn Trong Thư Viện HTTP Client Phổ Biến Nhất
Ngày 31 tháng 3 năm 2026, kẻ tấn công chiếm quyền tài khoản npm của maintainer axios và phát hành hai phiên bản chứa mã độc cài trojan truy cập từ xa đa nền tảng thông qua một dependency giả. Đây là cách cuộc tấn công hoạt động, cách kiểm tra xem bạn có bị ảnh hưởng, và cách xử lý.
Table of Contents
Chuyện Gì Đã Xảy Ra
Vào ngày 31 tháng 3 năm 2026, hai phiên bản chứa mã độc của axios — thư viện HTTP client JavaScript phổ biến nhất với hơn 100 triệu lượt tải mỗi tuần — đã được phát hành lên npm. Kẻ tấn công chiếm quyền tài khoản npm của maintainer chính và dùng nó để tiêm một dependency giả, cài đặt trojan truy cập từ xa (RAT) đa nền tảng lên mọi máy chạy npm install.
Các phiên bản bị xâm nhập tồn tại khoảng 2,5 đến 4,5 giờ trước khi npm gỡ chúng. Trong hệ sinh thái npm, chừng đó thời gian là đủ để gây thiệt hại nghiêm trọng.
Bài viết này dựa trên phân tích chi tiết của StepSecurity về sự cố.
Cách Cuộc Tấn Công Hoạt Động
Chiếm Quyền Tài Khoản
Kẻ tấn công chiếm quyền tài khoản npm jasonsaayman — maintainer chính của axios. Email đăng ký bị đổi thành địa chỉ ProtonMail do kẻ tấn công kiểm soát ([email protected]). Điều này khả thi vì tài khoản sử dụng npm access token dài hạn thay vì cơ chế OIDC Trusted Publisher an toàn hơn. Một token bị đánh cắp là đủ.
18 Giờ Chuẩn Bị Trước
Đây không phải kiểu tấn công vội vàng. Kẻ tấn công chuẩn bị trong 18 giờ:
| Thời gian (UTC) | Sự kiện |
|---|---|
| 30/3, 05:57 | [email protected] phát hành bởi [email protected] — mồi nhử sạch để thiết lập package |
| 30/3, 23:59 | [email protected] phát hành — thêm postinstall hook chứa mã độc |
| 31/3, 00:21 | [email protected] phát hành — tiêm plain-crypto-js@^4.2.1 làm runtime dependency |
| 31/3, 01:00 | [email protected] phát hành — cùng payload, nhắm vào nhánh 0.x |
| 31/3, ~03:15 | npm gỡ cả hai phiên bản axios |
| 31/3, 03:25 | npm đặt security hold lên plain-crypto-js |
Điểm mấu chốt: plain-crypto-js không bao giờ được import ở bất kỳ đâu trong source code axios. Mục đích duy nhất của nó là thực thi postinstall script. Một dependency xuất hiện trong manifest nhưng không được sử dụng trong code là dấu hiệu đáng tin cậy cao của bản phát hành bị xâm nhập.
Bộ Cài RAT
Hook postinstall chạy setup.js — file 4,2 KB bị obfuscate với hai lớp mã hóa: XOR cipher (key: OrDeR_7077) và base64. Nó chạy trong ~2 giây kể từ npm install, liên lạc với máy chủ C2 trước khi npm hoàn thành resolve dependency, sau đó tự hủy — xóa setup.js và thay thế package.json chứa mã độc bằng một stub sạch báo phiên bản 4.2.0 (không phải 4.2.1) để tránh bị phát hiện khi kiểm tra.
Payload Theo Từng Nền Tảng
Bộ cài phát hiện hệ điều hành và gửi payload phù hợp:
| Nền tảng | Vị trí RAT | Phương thức thực thi |
|---|---|---|
| macOS | /Library/Caches/com.apple.act.mond | AppleScript qua /bin/zsh |
| Windows | %PROGRAMDATA%\wt.exe (bản sao PowerShell giả dạng Windows Terminal) | VBScript dropper → PowerShell stage-2 ẩn |
| Linux | /tmp/ld.py | nohup python3 chạy nền |
Máy chủ C2 tại sfrclak.com:8000 (IP: 142.11.206.73). POST body được thiết kế trông giống traffic npm registry bình thường — packages.npm.org/product0 cho macOS, product1 cho Windows, product2 cho Linux.
Làm Sao Biết Mình Có Bị Ảnh Hưởng
Kiểm Tra Phiên Bản Đã Cài
Các phiên bản bị xâm nhập là [email protected] và [email protected]. Phiên bản an toàn là 1.14.0 và 0.30.3.
# Check if you have a compromised version installed
npm list axios 2>/dev/null | grep -E "1\.14\.1|0\.30\.4"
# Check your lockfile
grep -A1 '"axios"' package-lock.json | grep -E "1\.14\.1|0\.30\.4"
Kiểm Tra Dependency Độc Hại
Package này không bao giờ tồn tại trong bất kỳ bản cài axios chính thống nào:
# If this directory exists, you were compromised
ls node_modules/plain-crypto-js 2>/dev/null && echo "POTENTIALLY AFFECTED"
Kiểm Tra Dấu Vết RAT Trên Máy
# macOS
ls -la /Library/Caches/com.apple.act.mond 2>/dev/null && echo "COMPROMISED"
# Linux
ls -la /tmp/ld.py 2>/dev/null && echo "COMPROMISED"
# Windows (PowerShell)
if (Test-Path "$env:PROGRAMDATA\wt.exe") { Write-Host "COMPROMISED" }
Kiểm Tra Log Mạng
Tìm kết nối đến hạ tầng C2:
# Check active connections
ss -tunap | grep -E "sfrclak\.com|142\.11\.206\.73"
# Check DNS logs if available
grep -r "sfrclak.com" /var/log/
Lưu ý quan trọng: Mã độc tự hủy sau khi thực thi. Nếu nó đã chạy thành công,
npm listsẽ hiển thị[email protected](stub sạch), không phải4.2.1. Việc không thấy dấu vết rõ ràng không đảm bảo bạn không bị xâm nhập — RAT có thể vẫn đang chạy.
Các Bước Khắc Phục
1. Hạ Phiên Bản Ngay Lập Tức
# For 1.x users
npm install [email protected]
# For 0.x users
npm install [email protected]
2. Ghim Phiên Bản Bằng Overrides
Thêm vào package.json để ngăn transitive dependency kéo phiên bản xấu:
{
"dependencies": { "axios": "1.14.0" },
"overrides": { "axios": "1.14.0" },
"resolutions": { "axios": "1.14.0" }
}
3. Gỡ Package Độc Hại
rm -rf node_modules/plain-crypto-js
npm install --ignore-scripts
4. Nếu Tìm Thấy Dấu Vết RAT — Xóa Sạch Từ Đầu
Không cố gắng dọn dẹp tại chỗ. Nếu bất kỳ dấu vết RAT nào xuất hiện trên máy:
- Dựng lại hệ thống từ trạng thái sạch — reimage, deploy lại từ base sạch
- Xoay vòng TẤT CẢ thông tin xác thực có thể truy cập từ máy bị xâm nhập:
- npm token
- AWS/GCP/Azure access key
- SSH private key
- CI/CD secret và biến môi trường
- Tất cả trong file
.env
- Kiểm tra log pipeline CI/CD cho bất kỳ
npm installnào chạy trong khoảng thời gian bị xâm nhập (31/3, 00:21–03:15 UTC)
5. Chặn C2 Ở Tầng Mạng
# Linux firewall
iptables -A OUTPUT -d 142.11.206.73 -j DROP
# Hosts file (macOS/Linux)
echo "0.0.0.0 sfrclak.com" >> /etc/hosts
6. Gia Cố CI/CD Từ Đây Về Sau
# Use --ignore-scripts to prevent postinstall hooks
npm ci --ignore-scripts
Lệnh này chặn vector tấn công chính — postinstall script — với cái giá là phá hỏng các package thực sự cần bước build. Cho môi trường CI/CD production, sự đánh đổi này gần như luôn đáng.
Những Điều Cần Nhớ
-
Một npm token bị xâm nhập duy nhất cho kẻ tấn công quyền publish lên package 100 triệu lượt tải mỗi tuần. Access token dài hạn là mắt xích yếu nhất. Dùng OIDC Trusted Publisher hoặc token ngắn hạn bất cứ khi nào có thể.
-
Cuộc tấn công được thiết kế chính xác, không phải tình cờ. Giai đoạn chuẩn bị 18 giờ, RAT payload đa nền tảng, tự hủy chống phân tích, và traffic C2 giả dạng request npm registry. Đây là công trình cấp chuyên nghiệp.
-
postinstallscript là bề mặt tấn công nguy hiểm. Chúng thực thi code tùy ý lúc cài đặt mà không cần xác nhận người dùng. Dùng--ignore-scriptstrong CI/CD và kiểm tra hookpostinstalltrong cây dependency. -
Dependency “ma” là dấu hiệu cảnh báo. Dependency xuất hiện trong manifest nhưng không bao giờ được import trong source code là chỉ báo đáng tin cậy cao của bản phát hành bị xâm nhập. Các công cụ so sánh manifest với import thực tế có thể bắt lỗi này tự động.
-
Cửa sổ 2,5 giờ là đủ. Dù npm phản ứng tương đối nhanh, khoảng thời gian bị xâm nhập đủ dài để ảnh hưởng build trên toàn thế giới. Giám sát thời gian thực các package registry — như Harden-Runner của StepSecurity — đang trở thành hạ tầng thiết yếu.
Thảo Luận Tương Lai
Vấn Đề npm Token Mang Tính Hệ Thống
Cuộc tấn công này khai thác npm access token dài hạn. npm hỗ trợ OIDC Trusted Publisher — cơ chế publish thông qua pipeline CI/CD được xác minh thay vì token cá nhân — nhưng mức độ áp dụng còn thấp. Cho đến khi hệ sinh thái bắt buộc token ngắn hạn, giới hạn phạm vi theo mặc định, máy cá nhân của mỗi maintainer là single point of failure cho toàn bộ cây dependency.
postinstall Cần Được Suy Nghĩ Lại
Hook npm postinstall có công dụng chính đáng (biên dịch native module, tải binary), nhưng nó cũng là vector bị lạm dụng nhiều nhất trong tấn công chuỗi cung ứng. Cộng đồng đã tranh luận về sandbox hoặc yêu cầu opt-in rõ ràng cho install script nhiều năm nay. Sự cố này nhiều khả năng sẽ thúc đẩy cuộc thảo luận đó. Trong lúc chờ đợi, --ignore-scripts là mặc định thực dụng cho môi trường CI/CD.
Provenance của Dependency Là Lớp Còn Thiếu
Các package registry hiện tại xác minh rằng việc publish đến từ tài khoản được ủy quyền — nhưng không xác minh nội dung phát hành khớp với bất kỳ source repository nào. Nếu npm yêu cầu [email protected] phải khớp với tagged commit trong repo GitHub axios, cuộc tấn công này đã thất bại. Sigstore và provenance attestation của npm đang đi đúng hướng, nhưng mức độ áp dụng vẫn còn thấp.
Phát Hiện Bằng AI Đang Trở Nên Cần Thiết
StepSecurity phát hiện cuộc xâm nhập này bằng phân tích tự động đánh dấu plain-crypto-js là bất thường — dependency mới không có import tương ứng trong codebase. Khi tấn công chuỗi cung ứng ngày càng tinh vi, review code thủ công lúc cài đặt không khả thi với cây dependency hàng trăm package. Giám sát tự động hành vi package bằng AI đang chuyển từ “có thì tốt” sang hạ tầng thiết yếu.
Tham Khảo
- StepSecurity: Axios Compromised on npm — Malicious Versions Drop Remote Access Trojan
- GitHub Issue #10604 — axios
- Malicious package shasum:
[email protected](2553649f232204966871cea80a5d0d6adc700ca),[email protected](d6f3f62fd3b9f5432f5782b62d8cfd5247d5ee71) - Dropper SHA-256:
e10b1fa84f1d6481625f741b69892780140d4e0e7769e7491e5f4d894c2e0e09
Bai viet lien quan
- Giải Phẫu Cuộc Tấn Công Chuỗi Cung Ứng LiteLLM — Khi Công Cụ Bảo Mật Trở Thành Vũ Khí
- Khi Malware Gọi Lên Cloud Xin Chỉ Thị — Case Study Về Tấn Công Mạng Bằng AI
- Bleeding Llama — Khi Một File GGUF Có Thể Hút Cạn Bộ Nhớ Máy Chủ Ollama Của Bạn
- Claude Code vs OpenClaw vs NemoClaw — AI Agent Nào Phù Hợp Với Bạn?
- Parallelization: Thực thi đồng thời cho quy trình Agentic