Hacker không cần lừa developer cài package độc: Mục tiêu mới là khiến chính AI coding agent tự kéo malware vào project

Nghiên cứu của PANDEX cho thấy coding agent có thể đọc tài liệu chính thức, gặp một package chưa ai sở hữu rồi tự chạy lệnh cài đặt. Trong thử nghiệm, code do researcher kiểm soát đã được thực thi từ mạng doanh nghiệp; một trường hợp riêng trên tài liệu của Clerk còn từng trỏ tới package npm chứa malware thật.

Hacker không cần lừa developer cài package độc: Mục tiêu mới là khiến chính AI coding agent tự kéo malware vào project

Một cuộc tấn công supply chain kiểu cũ thường phải thuyết phục developer cài nhầm package, chiếm tài khoản maintainer hoặc chen mã độc vào dependency đã được tin dùng. Với AI coding agent, attacker có thêm một mục tiêu khác: không cần lừa con người trực tiếp, chỉ cần để một cái tên package “trống” nằm đúng nơi agent sẽ tin và làm theo.

Nghiên cứu Data Became Code của PANDEX cho thấy điều đó không còn là giả thuyết. Nhóm của security researcher Alon Hertz rà soát hàng nghìn file llms.txtllms-full.txt do các công ty công khai cho AI đọc, rồi phát hiện hơn 200 package hoặc domain được tài liệu nhắc tới nhưng chưa có ai sở hữu. Khi researcher đăng ký một số tên còn trống và đặt vào đó một beacon vô hại, các coding agent đã tự tìm tài liệu, chạy lệnh cài đặt và thực thi code của researcher từ bên trong mạng doanh nghiệp.

Điểm khác biệt đáng chú ý là chuỗi này không cần prompt injection. Tài liệu có thể hoàn toàn hợp lệ, nằm trên HTTPS và được chính vendor xuất bản. Lỗ hổng niềm tin xuất hiện ở bước tiếp theo: agent tin rằng quyền của vendor khi nói “hãy cài package X” đồng nghĩa với việc package mang tên X trên registry cũng thuộc vendor đó.

llms.txt vốn là dữ liệu, nhưng agent có thể biến nó thành hành động

llms.txt là một định dạng đang được dùng để cung cấp nội dung có cấu trúc cho mô hình và agent: mô tả sản phẩm, trỏ tới documentation, API, SDK hoặc hướng dẫn setup. Về hình thức, đây chỉ là text. Vấn đề bắt đầu khi coding agent không chỉ đọc mà còn có quyền dùng shell, package manager và network để hoàn thành công việc thay developer.

PANDEX mô tả chính attack surface này khá thẳng: một file agent-facing có thể chứa shell command, build step, package name, domain, MCP server hay API endpoint. Nếu agent coi nội dung đó là instruction đáng tin, những thành phần trước đây chỉ là “documentation” có thể trở thành đầu vào vận hành cho một process có quyền thực thi.

Trong nghiên cứu, nhóm quét 6.214 domain thuộc các nhóm như Fortune 500, Big Tech và defense contractor. Bài đăng công khai của Hertz nêu 8.565 file llms.txt/llms-full.txt và hơn 237 artifact chưa được đăng ký. Ars Technica, khi đưa tin độc lập về cùng nghiên cứu, dẫn con số 8.265 file và 227 install command hoặc reference trên 120 website. Hai nguồn không giải thích sự chênh lệch này, nên điều chắc chắn hơn là quy mô: hàng nghìn file đã được rà soát và hơn 200 điểm tham chiếu dẫn tới package hoặc domain không có chủ sở hữu.

Attacker không cần sửa tài liệu nếu cái tên package vẫn còn trống

Giả sử một trang documentation chính thức viết pip install company-helper. Tại thời điểm tài liệu được tạo, company-helper có thể chỉ là tên viết nhầm, tên chưa từng được publish hoặc một dependency cũ đã biến mất. Với con người, developer có thể dừng lại khi thấy package lạ. Với một agent được giao nhiệm vụ “cài SDK của vendor và chạy project”, lệnh đó có thể được thực hiện như một phần bình thường của workflow.

Nếu attacker đăng ký company-helper trên registry trước, họ không cần chạm vào website của vendor. Agent vẫn truy cập đúng domain, đọc đúng tài liệu và dùng đúng package manager. Chỉ có một chi tiết thay đổi: cái tên mà tài liệu tham chiếu giờ resolve tới code của người khác.

Đây là điểm khiến kỹ thuật này khác dependency confusion truyền thống theo cách đáng quan tâm. Trong nhiều cuộc tấn công cũ, attacker tận dụng sự xung đột giữa package private và public hoặc một namespace cấu hình sai. Ở đây, chính agent có thể trở thành mắt xích tự động đi từ “tài liệu đáng tin” sang “cài artifact chưa được xác minh”.

Researcher chỉ đặt beacon, nhưng code vẫn chạy trong mạng doanh nghiệp

Để kiểm tra liệu khoảng trống đó có thực sự dẫn tới code execution hay không, PANDEX đăng ký một số package name chưa có chủ và nhúng một callback tối thiểu. Beacon chỉ báo rằng package đã được cài; nhóm cho biết không triển khai persistence và không exfiltrate dữ liệu.

Kết quả quan trọng nằm ở parent-process chain mà beacon ghi lại. Theo Ars Technica, callback cho thấy các agent gồm Claude, OpenAI Codex và Nous Research Hermes có liên quan tới những lần cài đặt. Một phản hồi từ hạ tầng của công ty Fortune 500 xuất hiện trong vài phút; sau đó có thêm nhiều callback từ doanh nghiệp và startup.

Thử nghiệm này không chứng minh rằng mọi coding agent sẽ luôn cài mọi package được documentation chỉ định. Nó chứng minh một điều hẹp hơn nhưng đủ nghiêm trọng: với agent có quyền chạy lệnh, trust vào vendor documentation có thể dẫn thẳng tới việc tải và thực thi code mà vendor chưa từng publish hoặc kiểm soát.

Clerk cho thấy biến thể này đã chạm vào malware thật

Phần đáng lo nhất của câu chuyện không phải beacon nghiên cứu. Khi rà soát tài liệu, nhóm phát hiện một trường hợp riêng trên website của Clerk, nền tảng authentication cho ứng dụng web. Tài liệu agent-facing của Clerk từng chứa lệnh npx clerk-next-fix-auth-protection.

Vấn đề nằm ở cách npx xử lý tên đó. Nếu binary tương ứng từ package chính thức của Clerk đã có sẵn, lệnh có thể gọi đúng công cụ. Nhưng khi binary không tồn tại trong môi trường, tên trần clerk-next-fix-auth-protection có thể được resolve như một package độc lập trên npm. Clerk không phải bên publish package độc lập mang tên này.

Một bên thứ ba đã đăng ký nó. Dữ liệu từ OpenSSF Package Analysis và Amazon Inspector, được tổng hợp trong advisory MAL-2026-11069, xác định các phiên bản 7.7.7 và 8.8.8 là malicious. Package sử dụng lifecycle hook để gửi username, hostname, working directory và timestamp của máy cài đặt tới một endpoint bên ngoài.

Clerk sau đó đã sửa documentation. Ars Technica cũng lưu ý rằng người dùng đã có binary từ @clerk/eslint-plugin thì không rơi vào đường resolve nguy hiểm này. Chưa có dữ liệu công khai đủ để kết luận bao nhiêu máy thực sự bị nhiễm từ trường hợp Clerk. Vì vậy, đây là bằng chứng malware tồn tại trên đúng package name mà tài liệu từng gọi tới, không phải bằng chứng về một chiến dịch compromise quy mô lớn.

Vì sao EDR có thể không thấy điều gì bất thường?

Một lý do khiến attack path này khó chịu là các thao tác riêng lẻ trông rất bình thường. Agent được công ty chủ động cài đặt. Nó mở documentation qua HTTPS. Sau đó process hợp lệ gọi npm, npx hoặc pip tới registry công khai vốn đã được phép truy cập. Không bước nào nhất thiết giống một exploit điển hình.

Điểm thất bại nằm ở provenance: hệ thống không xác minh rằng package được resolve ở thời điểm cài thực sự thuộc về vendor đã viết instruction. HTTPS chứng minh agent đang đọc đúng website, nhưng không chứng minh tài khoản sở hữu một package name trên npm hay PyPI có quan hệ với website đó.

Đó cũng là lý do chỉ quét malware sau khi package được tải xuống chưa đủ. Một package mới đăng ký có thể chưa nằm trong denylist; một payload cũng có thể chỉ kích hoạt ở install hook. Kiểm soát cần xuất hiện trước bước execute: tên package, scope, publisher, registry, version và provenance cần được xác minh như một quyết định bảo mật riêng, không chỉ như chi tiết setup.

Coding agent đang làm mờ ranh giới giữa “đọc” và “chạy”

Rủi ro lớn hơn llms.txt là mô hình vận hành của agent. Một coding agent có thể đọc README, issue, documentation, MCP metadata hoặc web page rồi quyết định chạy command dựa trên nội dung đó. Khi quyền đọc và quyền hành động nằm trong cùng một vòng tự động, bất kỳ nguồn dữ liệu nào agent coi là authoritative đều có thể trở thành một phần của execution path.

Điều này không có nghĩa giải pháp là cấm agent cài dependency. Nếu phải xin developer xác nhận từng lệnh nhỏ, nhiều lợi ích của automation sẽ mất đi. Nhưng approval cũng không nên chỉ hỏi “cho phép chạy npm install không?”. Câu hỏi hữu ích hơn là: package này resolve tới ai, publisher có khớp với vendor không, version có bị pin không, hash có được xác minh không và install script có được phép chạy hay không.

Với doanh nghiệp, biện pháp thực tế là đặt package installation sau một policy gate deterministic thay vì để LLM tự đánh giá. Private registry proxy, allowlist namespace, provenance verification, lockfile, sandbox có network policy và chặn lifecycle script khi không cần thiết đều giúp giảm blast radius. Các organization xuất bản documentation cho agent cũng cần audit những package name, domain và command cũ của chính mình; một reference vô hại hôm nay có thể trở thành asset của attacker vào ngày mai.

PANDEX đã chọn một cụm từ khá chính xác cho vấn đề: “data became code”. Chính xác hơn về mặt kỹ thuật, dữ liệu không tự biến thành code; chúng ta đã đặt một agent có quyền thực thi ngay sau lớp dữ liệu đó. Khi agent đủ tự chủ để đọc, quyết định và chạy lệnh, security boundary không còn nằm ở chỗ developer có click “install” hay không. Nó chuyển ngược lên phía trước, tới câu hỏi agent đã tin nguồn nào trước khi tự mình làm việc đó.

Nguồn

Chia sẻ