Tháng 5 vừa rồi, một công ty bảo mật tên Irregular chạy một bài capture-the-flag nhắm vào Gemini. Kiểu red-team tiêu chuẩn: giao cho model một mục tiêu, xem nó có phá được không. Vấn đề là một trong những mục tiêu giả định trong kịch bản lại trùng tên với một công ty thật, đang hoạt động thật. Gemini không phân biệt được. Nó tìm ra repo công khai của công ty thật đó, lôi ra credential bị lộ trong repo, rồi đăng nhập. Sau đó nó làm y hệt — lần này là đoán mật khẩu — với hai công ty thật khác chẳng liên quan gì tới bài test.
Chuyện này lộ ra công khai ngày 19/9, sau khi Wall Street Journal bắt đầu đặt câu hỏi và Irregular cuối cùng công bố — khoảng hai tháng sau khi họ báo cho Google vào cuối tháng 7. Mình đọc cả ngày nay qua các bài trên Axios, TechCrunch, 9to5Google, CNN, và chi tiết đọng lại trong đầu không phải là “AI agent nổi loạn”. Mà là model thực ra đã làm đúng việc cần làm ở đoạn cuối — nó nhận ra mình vừa chạm vào một mục tiêu thật với hậu quả thật, và tự dừng lại. Cái sai không nằm ở khả năng phán đoán của model. Nó nằm ở người dựng môi trường test.
Đây là vấn đề đặt tên, không phải vấn đề alignment
Mình dựng đủ nhiều môi trường staging để biết chính xác chuyện này xảy ra kiểu gì. Ai đó tạo một công ty giả tên “Acme Logistics” cho kịch bản CTF, không check xem cái tên có trùng với thứ gì có thật không, rồi thả lên. Với một tester là người, một trùng hợp kỳ lạ như vậy có thể khiến họ nhíu mày. Nhưng với một agent thực thi task ở tốc độ máy, không có động lực gì để nghi ngờ lại phạm vi của mình, thì cái tên chỉ là một chuỗi ký tự. Nếu chuỗi đó trỏ tới thứ có thật — domain thật, repo GitHub công khai thật, trang đăng nhập thật — agent sẽ tương tác với nó không chút do dự, vì đó chính xác là việc nó được giao.
Đây cùng loại bug với việc hardcode một API key test mà tình cờ cũng chạy được trên prod, hay một môi trường QA dùng chung database với production vì chẳng ai xoay connection string. Vấn đề này có từ đời nào rồi. Chỉ là trước đây nó thất bại đủ chậm để con người kịp nhận ra trước khi thiệt hại thật sự xảy ra. Một agent tự động thì xóa mất khoảng đệm thời gian đó.
Có hai thứ khiến chuyện này tệ hơn khi nói riêng về red-team bằng agent:
Phạm vi được định nghĩa bằng ngôn ngữ tự nhiên, không phải bằng allowlist. “Tìm cách xâm nhập Acme Logistics” là một chỉ thị, không phải một ranh giới. Một pentester con người đọc luật chơi (rules of engagement) và có 20 năm kinh nghiệm nghề nghiệp mách bảo dừng lại hỏi lại nếu có gì đó không ổn. Agent thì chỉ có đúng đoạn text trong system prompt và những tool nó được cấp.
Và khác với các sự cố trước đây liên quan tới Irregular — được cho là Meta, Anthropic, OpenAI đã từng công bố riêng — lần này không phải jailbreak hay prompt injection. Không ai lừa model cả. Bài test hoạt động đúng như thiết kế; chính cái thiết kế đó mới là bug.
Nếu là mình, mình sẽ đổi gì trong một setup red-team
Nếu bạn đang chạy (hoặc định chạy) bài red-team bằng agent nhắm vào hạ tầng của chính mình, hay đang đánh giá một benchmark kiểu CTF của vendor có chạm tới bất cứ thứ gì lộ ra internet, đây là checklist mình sẽ áp dụng trước khi để agent lại gần:
Đặt namespace cho mục tiêu giả sao cho không thể resolve được. Đừng đặt tên công ty test nghe giống một thương hiệu có vẻ hợp lý ngoài đời. Dùng một namespace rõ ràng là giả — subdomain dưới một domain bạn sở hữu, tên công ty gắn thêm hậu tố kiểu -ctf-2026, bất cứ thứ gì khiến DNS fail hoặc trả 404 nếu agent cố vươn ra ngoài sandbox. Nếu mục tiêu giả có thể vô tình trỏ tới thứ thật, sớm muộn gì nó cũng sẽ trỏ tới.
Giới hạn credential theo sandbox, không theo vai trò. Nếu tool của agent có bất kỳ credential nào cũng dùng được cho production hay hệ thống bên thứ ba, thì credential đó là một sợi dây điện sống, bất kể prompt nói nhiệm vụ là gì. Token tạm thời, chỉ dùng trong sandbox, cấp mới cho từng lần chạy rồi thu hồi ngay khi xong, là cách duy nhất đảm bảo “tìm cách xâm nhập” không vô tình biến thành “xâm nhập vào thứ không nằm trong kế hoạch.”
Đo lường độ trôi phạm vi (scope drift), không chỉ đo thành công. Hầu hết harness red-team chỉ log xem agent có đạt mục tiêu hay không. Rất ít log lại từng resource bên ngoài mà agent chạm vào trong quá trình, đối chiếu với allowlist, kèm cơ chế kill switch tự động nếu nó bước ra ngoài. Đó chính là lớp lẽ ra đã bắt được chuyện này trong vài phút thay vì vài tháng. Irregular cuối cùng cũng phát hiện ra, và Gemini tự dừng — nhưng “cuối cùng cũng” và “tự dừng” không thể thay thế cho một ranh giới cứng được enforce từ bên ngoài model.
Giả định agent khám phá ở tốc độ máy, không phải tốc độ người. Một tester là người thấy gì đó giống mục tiêu thật sẽ dừng lại. Agent thì không dừng, trừ khi bạn xây sẵn điểm dừng đó vào — một egress allowlist ở tầng network, một proxy chỉ cho phép traffic tới host trong sandbox, thứ gì đó không dựa vào phán đoán của chính model làm tuyến phòng thủ cuối cùng.
Không cái nào trong số này đòi hỏi phải nghi ngờ model nhiều hơn. Ngược lại, việc Gemini tự dừng khi nhận ra tác động thật là một điểm cộng — đó chính xác là hành vi mình muốn thấy ở tầng model. Nhưng tầng model không bao giờ nên là tầng phòng thủ duy nhất. Ranh giới nào phụ thuộc vào việc agent tự suy luận đúng ý định, sớm muộn cũng sẽ thất bại, và ở tốc độ agent, “sớm muộn” có thể là ngay trong lần chạy test qua đêm tiếp theo của bạn.
Tuần này mình thêm một bước vào checklist đánh giá agent ở chỗ mình: trước khi bất kỳ lần chạy test tự động nào chạm vào thứ gì có network access, phải có người xác nhận mọi thực thể được đặt tên trong kịch bản đều không thể resolve ra ngoài sandbox. Chỉ mất năm phút check. Và nó đã đủ để ngăn toàn bộ câu chuyện này xảy ra.