Hôm nay mình đọc báo cáo của Checkmarx về chiến dịch malware npm đang hoạt động và phải nói thẳng: đây là cú lừa được xây dựng tinh vi nhất mà mình thấy trong nửa năm qua. Package indexed-btree giả mạo thư viện sorted-btree hợp pháp, đạt 2 triệu lượt tải mỗi tuần, và điểm nguy hiểm nhất là nó không dùng install script — nghĩa là toàn bộ cơ chế phòng thủ mà GitHub áp dụng từ tháng 6/2026 đều bị nó lách qua. Nếu bạn làm web, kể cả chỉ làm theme WordPress có dùng npm cho build tool, bài này dành cho bạn.
Malware npm indexed-btree lách phòng thủ npm như thế nào?

Tháng 6/2026, GitHub chặn các lifecycle script như preinstall, install, postinstall trừ khi được duyệt tay. indexed-btree đơn giản là không dùng chúng nữa. Thay vào đó, kẻ tấn công giấu loader trong chính hàm cốt lõi của thư viện — BTree.prototype.set() — hàm mà ứng dụng nào dùng thư viện này cũng phải gọi liên tục. Khi app gọi set() với đúng một key value định sẵn, giai đoạn obfuscate đầu tiên trong sharedLoad.min.js mới thức tỉnh. Kết quả: lúc cài đặt package sạch bong, không trigger bất kỳ cơ chế duyệt nào của npm v12.
Sau khi kích hoạt, malware thu thập được gì?
Theo Checkmarx, sau khi chạy, malware thu thập thông tin hệ thống gồm kiến trúc CPU, hostname, bộ nhớ, uptime, rồi gửi ra ngoài qua kênh Slack và Telegram hardcode sẵn. Đáng chú ý hơn, nó poll một smart contract Ethereum trên mạng Sepolia testnet để lấy lệnh C2, dùng trao đổi khóa X25519 suy ra khóa AES rồi giải mã payload giai đoạn hai lưu ngay trong contract. Khi muốn kết thúc, nó tự xóa file và gỡ trigger khỏi code package để xóa dấu vết. Nếu bạn từng nghĩ testnet Ethereum vô hại thì đây là ví dụ sống nó đang được dùng làm C2 miễn phí.
Vì sao dev bị lừa tin package này?
Kẻ tấn công đầu tư nghiêm túc: dựng GitHub repository nhìn rất đàng hoàng, đô thị hóa commit history có nội dung thật, chăm sóc tài khoản developer qua nhiều tháng. Đây không phải kiểu typosquat vụng về mà là social engineering toàn diện. Ngoài indexed-btree, Checkmarx còn phát hiện 9 package cùng đường dây đã bị gỡ khỏi npm, gồm btree-core (1,9 triệu lượt tải), btree-leaderboard (493.685), btree-range-store (468.092), ordered-kv-index (448.184), sliding-score-window (448.024), btree-time-index (425.312), priority-slot-queue (402.860), btree-lru-cache (372.185) và neighbor-key-map (366.019). Con số lượt tải cho thấy quy mô ảnh hưởng rất lớn.
Cách kiểm tra project có dính package độc không?
Mình làm việc này trong 5 phút với 3 lệnh sau. Đứng ở thư mục gốc project, chạy:
# Liệt kê toàn bộ dependency đang cài, kể cả transient
npm ls --all 2>/dev/null | grep -iE "indexed-btree|btree-core|btree-leaderboard|btree-range-store|ordered-kv-index|btree-time-index|btree-lru-cache|priority-slot-queue|neighbor-key-map|sliding-score-window"
# Rà luôn trong lockfile để bắt cả package từng được ghi lại
grep -iE "indexed-btree|btree-core|btree-leaderboard|sliding-score-window" package-lock.json
# So sánh chính tả với package gốc, ví dụ bạn cần sorted-btree
npm ls sorted-btree
Nếu grep trả về kết quả nào, đừng cố gỡ tay từng cái. Xóa thư mục node_modules và package-lock.json, gỡ dependency đó khỏi package.json, thay bằng thư viện gốc đúng chính tả rồi cài lại từ đầu.
Dính rồi thì phải xử lý ra sao?
Checkmarx khuyến nghị rõ: rotate toàn bộ secret (API key, token, SSH key, biến môi trường production) và khôi phục môi trường dev từ backup sạch. Vì malware thu thập hostname, thông tin hệ thống và có thể tải payload giai đoạn hai, mình luôn giả định tối thiểu là nó đã đọc được mọi biến trong file .env. Nếu server deploy có chạy CI/CD tự động npm install, kiểm tra log build xem các package trên xuất hiện từ bao giờ:
# Xem log install gần nhất trên CI (ví dụ GitHub Actions)
grep -iE "indexed-btree|btree-core" .github/workflows/*.yml
# Trên server: tìm trong log deploy
zgrep -i "btree" /var/log/deploy*.log 2>/dev/null
Làm sao tránh Supply Chain Attack kiểu này về sau?
Bài học lớn nhất: scanning lúc install là không đủ, vì malware này chủ động né Install Script và chỉ chạy lúc runtime. Mình khuyên nhóm 4 việc sau cho mọi project, kể cả dự án WordPress chỉ dùng npm cho asset build:
- Khóa lockfile: commit
package-lock.json, bậtnpm citrong CI thay vìnpm installđể không có surprise version. - Review package trước khi thêm: kiểm tra ngày tạo repo, số maintainer, lịch sử commit. Packageclone ra tuần trước mà repo 3 năm “tuổi” là dấu hiệu clone.
- Chạy build trong môi trường cách ly: CI container không có secret production, để lộ thì cũng không mất gì.
- Runtime behavioral analysis: theo dõi outbound request lạ từ dev machine (Slack/Telegram webhook từ process node là tín hiệu đỏ kinh điển).
Nếu bạn quản lý site WordPress, đây là lúc rà lại toàn bộ toolchain của mình — mình đã có bài riêng về Supply Chain Attack với plugin WordPress và runbook rà soát 277 lỗ hổng trong 1 tuần bằng WP-CLI để bạn áp dụng ngay.
Câu hỏi thường gặp
indexed-btree có phải package hợp pháp không?
Không. Nó là bản giả mạo của thư viện sorted-btree hợp pháp, do Checkmarx phát hiện trong chiến dịch malware npm tháng 9/2026. Package thật bạn cần tên là sorted-btree.
Mình chỉ làm WordPress không dùng npm, có bị ảnh hưởng không?
Có thể, nếu theme hoặc build tool của bạn (Vite, webpack, Gulp) kéo dependency npm. File package.json trong theme không có nghĩa dự án miễn nhiễm với lỗ hổng npm.
npm chặn install script rồi sao malware vẫn chạy được?
Vì nó giấu malicious code trong hàm runtime của thư viện thay vì install script. Khi ứng dụng gọi hàm BTree.prototype.set() với key đặc định, malware mới kích hoạt nên né được kiểm duyệt lúc cài.
