Công cụ lập trình 97 triệu lượt tải mỗi tháng bị chèn mã độc cực nguy hiểm, cuối cùng bị lộ vì dùng vibe-coding quá ẩu
Nếu lần sau hacker cẩn thận hơn và không mắc lại sai lầm tương tự, liệu cơ hội giải cứu có đến lần thứ hai?
Câu chuyện bắt đầu từ một thao tác quen thuộc đến mức gần như vô thức với mọi lập trình viên: cài một thư viện bằng lệnh “pip install”. Không cảnh báo, không thông báo bất thường, mọi thứ diễn ra trơn tru như hàng triệu lần trước đó. Nhưng lần này, chỉ một dòng lệnh đơn giản đã đủ để mở ra cánh cửa cho một trong những kịch bản tấn công đáng sợ nhất trong thế giới phần mềm hiện đại.
Thư viện đó là LiteLLM, một package Python cực kỳ phổ biến với khoảng 97 triệu lượt tải mỗi tháng. Nó không chỉ được sử dụng trực tiếp mà còn nằm sâu trong hàng loạt dự án lớn dưới dạng dependency, nghĩa là ngay cả khi lập trình viên không chủ động cài đặt, nó vẫn có thể xuất hiện một cách “vô hình” trong hệ thống. Chính điều này khiến mức độ lan rộng tiềm tàng của sự cố trở nên đặc biệt nguy hiểm.
Âm thầm tấn công người dùng
Vào sáng ngày 24/3, một phiên bản mới của LiteLLM bất ngờ được tải lên hệ thống PyPI. Khác với quy trình phát hành thông thường, phiên bản này không đi kèm bất kỳ bản ghi phát hành hay cập nhật nào trên GitHub. Nó được đưa thẳng lên kho phân phối, bỏ qua toàn bộ các bước kiểm soát quen thuộc.
Ẩn bên trong phiên bản này là một đoạn mã độc được thiết kế cực kỳ tinh vi. Ngay khi thư viện được cài đặt, một file .pth sẽ tự động được thực thi mỗi lần Python khởi động. Điều đáng nói là quá trình này không cần import, không cần gọi hàm, thậm chí người dùng cũng không hề hay biết rằng có điều gì đang diễn ra phía sau.
Từ đây, toàn bộ hệ thống bắt đầu bị “lục soát”. Mã độc thu thập mọi dữ liệu nhạy cảm có thể tìm thấy: khóa SSH, thông tin đăng nhập các nền tảng đám mây như AWS, GCP, Azure, cấu hình Kubernetes, mật khẩu database, file .env chứa API key, lịch sử lệnh terminal, cấu hình Git, thậm chí cả ví tiền điện tử.
Sau khi gom đủ dữ liệu, chúng được nén lại, mã hóa bằng thuật toán AES-256 và khóa RSA 4096-bit, rồi gửi về một máy chủ bên ngoài thông qua kết nối HTTP. Tất cả diễn ra âm thầm, không để lại dấu hiệu rõ ràng nào cho người dùng.
Không dừng lại ở việc đánh cắp thông tin, mã độc còn tìm cách mở rộng quyền kiểm soát. Nếu phát hiện môi trường Kubernetes, nó sẽ cố gắng truy cập toàn bộ secret trong cluster, sau đó triển khai các container có quyền cao trên từng node để cài backdoor. Trên máy cá nhân, nó cũng thiết lập cơ chế tồn tại lâu dài thông qua các service chạy nền, đảm bảo ngay cả khi khởi động lại máy, quyền truy cập vẫn được duy trì.
Trong một kịch bản hoàn hảo, đây có thể trở thành một cuộc tấn công quy mô lớn mà không ai hay biết. Với hàng chục triệu lượt tải mỗi tháng và vô số dự án phụ thuộc, chỉ cần vài ngày, mã độc có thể len lỏi vào hàng nghìn hệ thống, từ startup nhỏ đến hạ tầng của các tập đoàn lớn.
Nhưng rồi một chi tiết tưởng chừng vô nghĩa lại làm thay đổi toàn bộ cục diện.
Bị lộ bởi một sơ suất không ai ngờ tới
Một lập trình viên đang sử dụng Cursor cùng plugin MCP vô tình kéo LiteLLM về như một dependency gián tiếp. Anh không hề biết mình vừa cài đặt một phiên bản nhiễm độc. Nhưng ngay sau đó, máy tính bắt đầu có dấu hiệu bất thường. RAM bị chiếm dụng liên tục, hệ thống chậm dần rồi đột ngột sập hoàn toàn.
Sự cố này ban đầu chỉ giống như một lỗi kỹ thuật thông thường. Nhưng khi kiểm tra sâu hơn, nguyên nhân thực sự mới dần lộ diện. Đoạn mã độc bên trong litellm đã tự tạo ra một vòng lặp vô hạn: mỗi khi Python khởi động, nó lại sinh ra một tiến trình mới, và tiến trình đó lại kích hoạt chính đoạn mã ban đầu. Hiện tượng “fork bomb” này nhanh chóng làm cạn kiệt tài nguyên hệ thống và khiến máy bị treo.
Chính lỗi lập trình này đã vô tình “tố cáo” toàn bộ cuộc tấn công.
Nếu mã độc được viết cẩn thận hơn, nó hoàn toàn có thể hoạt động âm thầm, thu thập dữ liệu và gửi đi mà không gây ra bất kỳ dấu hiệu nào. Khi đó, việc phát hiện có thể bị trì hoãn hàng tuần, thậm chí lâu hơn, và hậu quả sẽ lớn hơn rất nhiều.
Theo nhận định của các chuyên gia, đây là minh chứng rõ ràng cho một rủi ro ngày càng lớn trong ngành phần mềm: tấn công chuỗi cung ứng. Mỗi lần cài đặt một thư viện không chỉ là tin tưởng vào tác giả của nó, mà còn là tin vào toàn bộ các dependency phía sau – một mạng lưới phức tạp mà ngay cả lập trình viên cũng khó kiểm soát hoàn toàn.
Điều khiến vụ việc trở nên đáng chú ý hơn là cách nó bị phát hiện. Không phải nhờ một hệ thống bảo mật tinh vi, cũng không phải do kiểm tra chủ động, mà chỉ vì kẻ tấn công… viết code quá ẩu. Trong bối cảnh “vibe-coding” – cách lập trình nhanh, dựa nhiều vào AI và tự động hóa – ngày càng phổ biến, chi tiết này mang một ý nghĩa đặc biệt.
Lần này, chính sự cẩu thả đã cứu cả hệ thống khỏi một cuộc tấn công âm thầm. Nhưng điều đó cũng đồng nghĩa với một thực tế đáng lo ngại hơn: nếu lần sau kẻ tấn công không mắc sai lầm tương tự, có thể sẽ không còn cơ hội thứ hai để phát hiện kịp thời.


