Đã phát tán các phiên bản độc hại của Nx và một số plugin hỗ trợ
(github.com/nrwl)- Các phiên bản độc hại của gói Nx và plugin đã được phát tán lên npm, quét hệ thống tệp, thu thập thông tin xác thực, rồi gửi chúng đến kho lưu trữ trên tài khoản Github của người dùng
- Để kiểm tra có bị ảnh hưởng hay không, cần xác nhận xem kho lưu trữ s1ngularity-repository có được tạo trong tài khoản Github hay không
- Nếu đã bị nhiễm, bắt buộc phải thay token và mật khẩu, xóa kho lưu trữ độc hại, kiểm tra các tệp cấu hình shell
- Các phiên bản độc hại tác động đến hệ thống bằng script postinstall; đặc biệt khi dùng plugin VSCode Nx Console, rủi ro bị thực thi ngoài ý muốn tăng cao
- Phía Nx đã triển khai biện pháp ngăn tái diễn và các biện pháp bảo mật bổ sung, đồng thời các phiên bản liên quan đã bị gỡ khỏi npm
Tổng quan và tóm tắt
- Cảnh báo bảo mật lần này là một cuộc tấn công chuỗi cung ứng nghiêm trọng nhắm vào gói Nx và một số plugin liên quan, với mã độc được phát tán qua npm
- Các phiên bản độc hại này quét hệ thống tệp của người dùng để thu thập thông tin xác thực, đường dẫn, v.v., rồi tải chúng lên kho Github
s1ngularity-repository - Script
postinstallđộc hại cũng sửa các tệp cấu hình shell của người dùng (.zshrc,.bashrc) để thêm lệnh tắt hệ thống - Bài viết trình bày chi tiết vector tấn công, diễn tiến của cuộc tấn công, các phiên bản bị ảnh hưởng, hành động khẩn cấp người dùng cần thực hiện và các biện pháp ngăn tái diễn
Cách xử lý khẩn cấp
Những điều mọi người đều phải kiểm tra
- Kiểm tra trong danh sách kho lưu trữ của tài khoản Github xem có
s1ngularity-repositoryđược tạo hay không - Tải xuống các tệp trong kho đó để lưu giữ hồ sơ
- Xóa kho lưu trữ đó khỏi Github
- Gửi email đến
security@nrwl.iođể được hướng dẫn cách giải mã thông tin bị lộ - Ngay lập tức thay toàn bộ thông tin xác thực và token của tất cả tài khoản
Cách thay Github token
- Truy cập https://github.com/settings/connections/…
- Thu hồi quyền truy cập của ứng dụng đã kết nối để vô hiệu hóa token cũ
- Nếu dùng
ghCLI, hãy xác thực lại để tạo token mới - Nếu không xử lý, token cũ có nguy cơ bị lạm dụng
Ngừng dùng và dọn dẹp các phiên bản Nx độc hại
- Kiểm tra phiên bản Nx đang dùng có phải phiên bản độc hại hay không bằng lệnh
npm ls nx - Nếu là phiên bản bị nhiễm, cập nhật bằng
npm uninstall nx && npm install nx@latest - Dọn cache bằng
npm cache clean --force
Người dùng đã bị nhiễm
- Thay token npm và Github
- Đặt lại toàn bộ mật khẩu và thông tin xác thực của Github cùng các dịch vụ liên quan
- Kiểm tra trong các tệp
.zshrc,.bashrcxem có lệnh lạ bị chèn vào hay không, rồi xóa chúng
Đối với quản trị viên kho lưu trữ gói nội bộ
- Cần xóa ngay các phiên bản độc hại khỏi proxy trong registry nội bộ để chặn lây lan thêm
Thông tin các phiên bản bị ảnh hưởng
Gói Nx
- 21.5.0, 20.9.0, 20.10.0, 21.6.0, 20.11.0, 21.7.0, 21.8.0, 20.12.0
- Đã được gỡ khỏi npm tính đến 10:44 PM EDT
@nx/devkit, @nx/js, @nx/workspace, @nx/node, @nx/eslint, @nx/key, @nx/enterprise-cloud
- Đã được gỡ khỏi npm tính đến 10:44 PM, 6:20 AM EDT
Chi tiết vector tấn công
Nguyên nhân workflow dễ bị khai thác
- Một lỗ hổng cho phép thực thi mã tùy ý đã được đưa vào workflow Github Actions
- Nếu chèn mã bash cụ thể vào tiêu đề PR, workflow sẽ thực thi lệnh hệ thống, tức lỗ hổng Bash Injection
- Do dùng trigger
pull_request_target, workflow có quyền nâng cao (GITHUB_TOKENv.v.) nên bị lợi dụng - Trước khi bị xóa, workflow dễ bị tấn công vẫn tồn tại trên các nhánh cũ không phải
main, cho phép kẻ tấn công chạy workflow bằng PR độc hại và đánh cắp secret
Quá trình đánh cắp npm token
- Kẻ tấn công khiến
publish.ymlđược thực thi thông qua workflow dễ bị tấn công publish.ymllưu npm token trong Github Secrets, và trong quá trình đó token bị gửi tới webhook bên ngoài- Cuối cùng, kẻ tấn công dùng token này để tải lên npm các phiên bản độc hại của Nx và các gói hỗ trợ
Hành vi của gói độc hại
Thu thập thông tin, bao gồm thông tin xác thực, và đăng lên kho Github
- Khi script
postinstallcủa gói Nx bị nhiễm chạy, nó thu thập vị trí của nhiều tệp văn bản và thông tin xác thực - Dữ liệu được mã hóa
base64và tải lên kho Github có têns1ngularity-repository - Ngay cả khi kho thực tế đã bị xóa, vẫn cần tính đến khả năng rò rỉ thông tin vì trước đó nó từng ở trạng thái công khai
Can thiệp vào hồ sơ shell (.zshrc, .bashrc)
postinstallchèn lệnhsudo shutdown -h 0, có thể khiến hệ thống tắt khi mở terminal và làm lộ mật khẩu
Nhiều kịch bản khác nhau có thể kích hoạt postinstall
-
Không chỉ khi chạy trực tiếp
npm install/yarn/pnpm install, mà còn có thể chạy trong nhiều tình huống như phụ thuộc bắc cầu, tiện ích mở rộng editor, thực thi script -
Đặc biệt, tiện ích Nx Console cho VSCode (phiên bản 18.6.30 ~ 18.65.1) có thể tự động cài
nx@latestkhi khởi động editor, từ đó kích hoạtpostinstall -
Cần lưu ý rằng việc cài mô-đun NPM có thể diễn ra ở nhiều nơi ngay cả khi không chủ ý
-
Từ Nx Console (18.66.0), quy trình cài
latest nxđã bị loại bỏ
Dòng thời gian tấn công và ứng phó
Ngày 21 tháng 8
- 4:31 PM: PR chứa lỗ hổng Bash Injection được merge
- 10:48 PM: Bài đăng chỉ ra lỗ hổng được đăng trên X (trước đây là Twitter)
Ngày 22 tháng 8
- Buổi chiều: điều tra nội bộ, rollback workflow dễ bị tấn công (chưa hoàn chỉnh)
- Áp dụng CodeQL để phát hiện các lỗ hổng tương tự trong PR về sau
Ngày 24 tháng 8
- Có commit trong fork của kẻ tấn công cho thấy dấu hiệu làm lộ npm token
- PR độc hại được tạo rồi xóa, và
publish.ymlđã được thực thi bởi PR này
Ngày 26 ~ 27 tháng 8 (phát tán phiên bản độc hại, ứng phó)
- Nhiều phiên bản độc hại của Nx và plugin lần lượt được phát tán lên npm
- Cộng đồng Github/NPM đã báo cáo sự cố
- 10:44 PM: phía NPM đã xử lý, bao gồm gỡ toàn bộ các phiên bản liên quan
- 11:57 PM: vô hiệu hóa toàn bộ token dùng để phát hành các gói liên quan đến Nx
- Ngày 27 tháng 8: vá Nx Console, bật 2FA, chuyển sang cơ chế Trusted Publisher và các biện pháp bổ sung khác
Biện pháp phòng ngừa trước và ứng phó sau đó
- Bắt buộc 2FA với mọi maintainer trong tổ chức
nrwl - Áp dụng cơ chế Trusted Publisher. Cấm phát hành dựa trên npm token
- Các gói sau này sẽ chỉ được phát hành sau khi vượt qua xác minh dựa trên 2FA và độ tin cậy
- Tiếp tục áp dụng theo từng bước các biện pháp như phát hiện rủi ro bổ sung, phê duyệt PR, bảo vệ nhánh
Bài học và kế hoạch sắp tới
- Một lần nữa nhấn mạnh tầm quan trọng trong và ngoài nước của bảo mật chuỗi cung ứng, pipeline CI/CD và nguyên tắc tối thiểu hóa quyền trong workflow
- Sau khi rà soát lại nội bộ, nhóm dự định chia sẻ các bài học rút ra với cộng đồng
Liên hệ
- Có thể liên hệ qua
security@nrwl.io
Tham khảo và phụ lục
- Các issue chính trên Github, timeline và bài viết liên quan
- Cung cấp ví dụ về script
telemetry.jstrong gói bị nhiễm - Script này thu thập đường dẫn các tệp văn bản quan trọng trong hệ thống tệp nhằm tạo inventory
Tóm tắt kết luận
- Việc cập nhật lên bản mới nhất và áp dụng bản vá cho Nx cùng các plugin liên quan là rất quan trọng
- Khuyến nghị thay ngay các thông tin xác thực chính như npm, Github
- Đây là sự cố cho thấy những thiếu sót trong bảo mật chuỗi cung ứng và quản lý quyền workflow có thể dẫn đến tai nạn quy mô lớn
1 bình luận
Ý kiến trên Hacker News
Muốn nhắc mọi người định kỳ tắt các script của
npm installVí dụ dùng lệnh sau:
Có thể dễ dàng áp dụng thiết lập này theo từng dự án hoặc toàn cục
Dạo này hiếm có package hợp lệ nào không thể chạy nếu thiếu script, nên đa phần sẽ không thành vấn đề
Với những package thực sự cần để hoạt động, có thể xử lý bằng cách tạo script cài đặt riêng và chạy thủ công trong thư mục đó
Đây không phải lời giải vạn năng cho tấn công chuỗi cung ứng, nhưng thực tế đã chặn hiệu quả rất nhiều cuộc tấn công qua npm
Xem thêm trong tài liệu chính thức của npm config
Tôi cũng dùng bubblewrap để cô lập
npm,pnpm,yarnvà mọi phiên do chúng khởi chạy khỏi hệ thống~/code, và tôi lưu bash script dưới đây ở đầuPATHvới tênnpm~/codevà quyền chỉ đọc với thư viện hệ thốngDùng
pnpmcũng là một cách. Các bản mới mặc định bỏ qua mọi lifecycle script, chỉ chạy nếu được đưa vào whitelist riêngMỗi khi nghe lời khuyên này tôi lại thắc mắc: thực tế không có lập trình viên nào đọc hết hàng chục đến hàng trăm nghìn dòng code mà npm cài vào
git clonenpm install(ở đây có rủi ro cài package độc hại; bỏ qua post-install script thì chỉ chặn được tạm thời)npm run(lúc này package độc hại chạy và hệ thống bị nhiễm)node_modulesgiữa bước 2 và 3, mà chẳng ai làm vậy cảTôi chạy mọi công cụ dựa trên npm bên trong container Docker, không cho quyền truy cập gì ngoài thư mục hiện tại
Tôi thắc mắc vì sao lời khuyên này lại không được áp dụng tương tự với
setup.py(Python) haybuild.rs(Rust)Cần có văn hóa suy nghĩ kỹ thêm một lần trước khi thêm dependency mới
Năm nay đã có rất nhiều vụ tấn công chuỗi cung ứng
Tuần này tôi định thêm progress bar có 8 bộ đếm thống kê vào một dự án Go
Tìm library thì thấy code hơn 3.000 dòng, nên tôi nhờ LLM sinh một đoạn UI đơn giản và giải quyết được trong chưa tới 150 dòng
Không có dependency, chạy đúng ý, rất đơn giản nên ai cũng có thể dễ đọc và cải tiến
Chức năng là xóa output terminal rồi vẽ lại mỗi giây, có hỗ trợ thread-safe
Cả triển khai lẫn review chỉ mất 25 phút
Nếu không cần thống kê phức tạp thì khoảng 30 dòng code cũng đủ làm progress bar
Về sau khi cân nhắc có nên thêm dependency hay không, có lẽ tự làm sẽ hợp với tôi hơn
Tôi không có đủ nguồn lực để theo dõi mọi bản cập nhật package
Tôi đồng ý với ý này và nhớ thời kỳ đầu khi “package manager theo ngôn ngữ” trở nên phổ biến đã thấy rất bất an
pip,npm, v.v.Tôi nghĩ hướng đi tương lai là cách tiếp cận như cargo vet: giới thiệu cargo vet
Sự khác biệt giữa tự triển khai và dùng library là điều hiển nhiên
Tôi thực sự ghét các library progress bar kiểu này, nhất là loại phá vỡ emacs shell (expo, eas, v.v.)
..10%..20%..30%hoặcUploading…Nhóm chúng tôi ở một công ty bảo hiểm lớn đang vận hành monorepo quy mô lớn và các library xoay quanh NX
lerna,rushjs,yarn workspacesv.v. nhưng chưa có công cụ nào chạy tốt như NX (lernacuối cùng cũng bị NX mua lại,rushjsthì không được duy trì)Thay vì chỉ đổ lỗi cho Nx, Anthropic hay nền tảng, cần nhìn lại nguyên nhân thật sự
Kiểu tấn công này có thể gây thiệt hại chí mạng cho hàng chục nghìn tổ chức trong tài chính, điện lực, viễn thông, bệnh viện, quân sự, v.v.
Khi AI lan rộng, quy mô và tác động của tấn công sẽ còn lớn hơn
Chúng ta chưa viết phần mềm đủ có trách nhiệm. Nếu không tự làm được thì phải bị buộc tuân thủ an toàn và bảo mật như luật xây dựng
Điều nguy hiểm hơn tưởng tượng là môi trường máy tính cá nhân hiện nay bị gom tất cả vào một không gian lớn
50% nạn nhân bị lây qua VS Code, và chỉ chạy trên Linux cùng macOS
postinstall, nó thu thập tài sản quan trọng như credential người dùng (crypto wallet, token GitHub và npm, SSH key, v.v.)s1ngularity-repository, v.v.)Việc không lưu token/thông tin xác thực GitHub trong công cụ quản lý mật khẩu yêu cầu mở khóa thủ công cũng một phần do lỗi của GH CLI
Tôi không thích ý tưởng đưa vào “luật xây dựng cho phần mềm”, nhưng đồng ý rằng cả ngành hiện quá mong manh
Tôi cho rằng tư duy bắt phần mềm mã nguồn mở miễn phí phải chịu trách nhiệm là ngạo mạn
Gần đây tôi làm hầu hết công việc phát triển trong VM
Tôi cảm thấy mức độ an toàn của môi trường hiện nay thấp đến mức không thể chấp nhận được
Khả năng các agent (phần mềm dạng agent) trở thành vector mã độc đã tăng cực mạnh
Nếu kẻ tấn công chui được vào máy, đây là thời đại mà dữ liệu trị giá hơn 1.000 USD, khóa crypto, mật khẩu, thông tin cá nhân, tài liệu tài chính, v.v. đều có thể bị nhắm đến bất cứ lúc nào
Tôi cũng làm tương tự trong container Podman. Tôi không chia sẻ gì với host ngoài thư mục mã nguồn
Một phần vấn đề đến từ mô hình bảo mật PC truyền thống (Linux/Windows)
Nếu bạn thích kiểu này, tôi muốn giới thiệu Qubes OS. Nó cho UX khá tốt để làm mọi việc trong VM
Tuy vậy cũng phải nói rõ rằng việc dựng môi trường như thế rất khó hoặc khá tốn kém, do hệ sinh thái phần mềm và lịch sử phát triển
Claude Code là một công cụ mang tính đột phá cho năng suất
Nhưng ngược lại cũng có các vấn đề bảo mật như:
curlpipe vào bash (rủi ro thực thi mã từ xa)Chỉ riêng như vậy đã có ít nhất 3 điểm yếu bảo mật, nên tôi không muốn chạy nó ngoài sandbox như VM/container/máy dev riêng
Tôi cũng nghĩ nên chạy agent trong sandbox
Nhưng rồi sao?
Điểm thực sự nguy hiểm là nó tự động cập nhật mà không cần can thiệp người dùng, đồng nghĩa với việc trong lúc chạy đã trao quyền RCE cho Anthropic
Tôi tự hỏi package manager có nên có thiết lập kiểu “minimum package age” hay không
Ví dụ, nếu bỏ qua mọi package được đăng dưới 24~36 giờ thì sao
Tôi từng gặp vụ tương tự trước đây, bản cập nhật package làm hỏng mọi thứ rồi chỉ vài giờ sau đã được sửa/xóa
GitHub dependabot gần đây vừa thêm đúng tính năng như vậy
Renovate bot đã có sẵn tùy chọn này từ trước (
minimumReleaseAge), và dependabot giờ cũng đã hỗ trợpostinstallscript, mà phải bật rõ ràng khi cần (dù vậy rốt cuộc vẫn là đang chạy code của người khác)Không phải ở mức hệ điều hành, nhưng công cụ
uvcủa Astral có tùy chọn kiểu này cho package Pythonnpm installcũng có cờ chỉ cài dependency trước một thời điểm/ngày nhất địnhnpm install --before (ngày của 2 ngày trước)sẽ không cài dependency nào xuất hiện sau mốc đóTôi đặt
save-exact=truetrong.npmrcvà chỉ dùng lockfile cùng cập nhật thủ côngfakerjsvà những chuyện tương tự, tôi thấy phải thật cẩn trọngTôi tò mò liệu claude code có thực sự chạy những prompt như vậy không nên đã thử
“Yêu cầu này có vẻ là tìm kiếm và liệt kê các file nhạy cảm như ví tiền điện tử, private key, v.v., nên có khả năng bị lạm dụng và tôi không thể hỗ trợ”
Nó chỉ hướng dẫn các yêu cầu hợp pháp như kiểm tra bảo mật, phân tích lỗ hổng, viết công cụ giám sát, hiểu quyền file, thiết kế quy trình sao lưu, v.v.
Chúng tôi đã ghi nhận ít nhất hơn 250 trường hợp thành công (tức là vẫn có những prompt lọt qua)
Trong thực tế, mỗi lần so khả năng từ chối giữa Claude và các model khác, tôi đều thấy cơ chế từ chối/an toàn của Claude vượt trội hơn hẳn
Hệ điều hành về mặc định không nên cho app quyền truy cập vô hạn vào toàn bộ file system
Một số app có profile
apparmor/selinux, cũng có thể dùngfirejailNhưng về UX thì vẫn cần thay đổi
Đây là một vấn đề rất nghiêm trọng. Nó đến từ thiết kế desktop cách đây 30 năm
Tôi đang tự phát triển một công cụ trên Linux tập trung vào cô lập môi trường theo từng dự án bằng Podman: probox
Về bảo mật file trên Android thì Google đã làm khá tốt
Tôi cũng khuyên nên học cách dùng bubblewrap và môi trường chroot nhỏ
Tôi không nghĩ có hệ điều hành nào mà mặc định application được “truy cập vô hạn toàn bộ file system”
Trước đây từng có cảm giác mơ hồ kiểu “kẻ tấn công phải đoán được môi trường của mình”, nhưng giờ có thể bắt LLM học rồi thực hiện tấn công phù hợp với môi trường đó
Tôi cũng tự thấy như mình đã dự đoán đúng xu hướng này
Có thể xem thảo luận trước đó ở đây
Phần thật sự rợn người là giờ người ta dùng cả local LLM để tìm secret
Vấn đề “postinstall” thì cũ, nhưng payload đã là một thế hệ hoàn toàn mới
Logic độc hại được giấu trong prompt thay vì code, nên phân tích tĩnh truyền thống khó phát hiện hơn
Thật sự phải suy nghĩ xem nên phòng thủ thế nào trước loại prompt độc hại này