Hiểu về Keyv npm worm: Vì sao một gói JavaScript có thể kéo theo hàng trăm bản phát hành độc hại

Chiến dịch Keyv npm worm cho thấy một điểm yếu quen thuộc của chuỗi cung ứng phần mềm hiện đại: chỉ một gói phụ thuộc bị nhiễm cũng có thể lan sang nhiều dự án, nhiều tài khoản phát hành và nhiều môi trường CI/CD trong thời gian rất ngắn. Theo The Hacker News, mã độc đầu tiên được xác nhận xuất hiện trong [email protected] ngày 4/8/2026, sau đó lan ra ngoài không gian tên Keyv và Cacheable.

Sự cố này đáng chú ý không chỉ vì số lượng gói bị ảnh hưởng. Nó còn cho thấy kẻ tấn công đang kết hợp nhiều điểm thực thi khác nhau: lifecycle script của npm, quyền publish của tài khoản bị chiếm, runner CI/CD, token nhà phát triển, hook trong Claude Code và cấu hình tác vụ của Visual Studio Code.

Điểm khởi phát từ một lifecycle script

Trong bản phát hành độc hại đầu tiên, gói [email protected] thêm lệnh node setup.mjs vào giai đoạn preinstall. Đây là một vị trí nhạy cảm vì npm có thể chạy lifecycle script trong lúc cài phụ thuộc, trước khi nhà phát triển kịp đọc kỹ nội dung gói.

Theo phân tích được The Hacker News dẫn lại từ SafeDep và Socket, stage đầu kiểm tra sự hiện diện của Bun, tải runtime nếu cần, rồi chuyển quyền thực thi cho một bundle đã biên dịch. Payload này có thể thu thập token GitHub, npm, khóa cloud, dữ liệu Vault, Kubernetes, cơ sở dữ liệu, private key và cả thông tin trong bộ nhớ của GitHub Actions runner.

JavaScript development environment and software supply chain

Vì sao worm có thể lan rộng

Khi mã độc chạy trong máy phát triển hoặc runner CI/CD, nó có thể tiếp cận thông tin xác thực dùng để publish gói mới. Nếu tài khoản đó có quyền phát hành trên npm, payload có thể sửa, tăng phiên bản và phát hành lại các gói mà tài khoản kiểm soát. Đây là cơ chế biến một sự cố đánh cắp credential thành một chuỗi phát tán tự động.

SafeDep xác nhận 353 phiên bản độc hại trên 79 tên gói, trong khi giám sát của họ ghi nhận phạm vi rộng hơn là 442 phiên bản trên 353 tên. Aikido sau đó báo cáo con số ít nhất 868 gói trên 1.381 phiên bản. Các con số này phản ánh quy mô artifact độc hại trên registry, không đồng nghĩa với số lượng máy nạn nhân đã thực thi payload.

Hook Claude Code và VS Code làm tăng bề mặt rủi ro

Sự cố còn có một lớp đáng chú ý khác: kho Keyv được ghi nhận còn giữ các hook dành cho Claude Code và Visual Studio Code. Cấu hình .claude/settings.json chứa hook SessionStart gọi tới tệp trong thư mục .vscode, còn .vscode/tasks.json có tác vụ môi trường chạy khi mở folder.

Những hook này không tự động chạy trong mọi môi trường mặc định. VS Code có cơ chế workspace trust và thường yêu cầu người dùng cho phép trước khi chạy tác vụ tự động. Tuy vậy, sự hiện diện của chúng cho thấy kẻ tấn công đang tìm thêm đường thực thi bên ngoài lifecycle script truyền thống, đặc biệt trong bối cảnh công cụ AI lập trình ngày càng được tích hợp sâu vào quy trình phát triển.

Provenance hợp lệ không đủ để kết luận an toàn

Một điểm quan trọng của chiến dịch là bản phát hành Keyv bị nhiễm vẫn có OpenID Connect và SLSA provenance hợp lệ vì nó đi qua workflow GitHub Actions chính thức của dự án. Điều này không làm cho mã nguồn trở nên an toàn. Provenance xác nhận đường build và danh tính quy trình phát hành, nhưng không bảo đảm rằng nội dung đầu vào trước khi build là sạch.

Trong các hệ thống phụ thuộc tự động, đây là bài học lớn: chữ ký, workflow hợp lệ và badge xác minh chỉ là một phần của chuỗi tin cậy. Nếu credential hoặc quy trình commit bị lạm dụng, hệ thống có thể xác nhận rất đúng một bản phát hành rất sai.

Điều đội kỹ thuật cần làm

Các tổ chức nên kiểm tra lockfile, cache CI/CD và lịch sử cài đặt để xác định chính xác tên gói và phiên bản đã được resolve, thay vì chỉ dựa vào nhãn latest hiện tại trên npm. Khi registry thay đổi nhanh, một danh sách blocklist cấp namespace có thể bỏ sót phiên bản độc hại hoặc đánh dấu nhầm bản phát hành sạch.

Với máy trạm hoặc runner đã cài phiên bản bị ảnh hưởng, nên xem môi trường đó là đã lộ credential. Tuy nhiên, SafeDep cảnh báo cần loại bỏ cơ chế watcher thu hồi token của mã độc trước khi xoay vòng khóa, vì thao tác revoke có thể kích hoạt handler do kẻ tấn công đặt sẵn. Sau đó mới tiến hành rotate token GitHub, npm, cloud, SSH/private key và các bí mật CI/CD liên quan.

Về phòng ngừa dài hạn, đội phát triển nên hạn chế lifecycle script không cần thiết, dùng npm phiên bản mới với chính sách chặn script dependency chưa được phê duyệt, tách quyền publish theo nguyên tắc tối thiểu, giám sát bất thường trong release workflow và kiểm tra cấu hình workspace của công cụ lập trình trước khi tin cậy một kho mã.

Kết luận

Keyv npm worm là lời nhắc rằng chuỗi cung ứng phần mềm không chỉ bị tấn công ở mã nguồn ứng dụng chính. Rủi ro có thể nằm trong gói phụ thuộc nhỏ, script cài đặt, workflow phát hành, token CI/CD và cả cấu hình công cụ mà nhà phát triển mở mỗi ngày. Với hệ sinh thái JavaScript có tốc độ phát hành cao, năng lực phản ứng phụ thuộc vào khả năng biết chính xác môi trường đã chạy phiên bản nào, bằng quyền nào và trong bối cảnh nào.

VNCyberS tổng hợp từ The Hacker News, SafeDep, Socket và Aikido

Liên hệ với chúng tôi

Email: [email protected]
Điện thoại: +84 903260277