- Gói Bitwarden CLI cho npm đã bị xâm phạm như một phần của cuộc tấn công chuỗi cung ứng Checkmarx đang diễn ra, và phạm vi ảnh hưởng hiện được xác nhận chỉ giới hạn ở bản dựng
@bitwarden/cli 2026.4.0
- Mã độc
bw1.js được đưa vào gói sử dụng cùng hạ tầng và kỹ thuật làm rối như audit.checkmarx[.]cx/v1/telemetry, đồng thời cũng khớp với dấu hiệu xâm phạm CI/CD thông qua GitHub Action bị cài độc hại
- Mục tiêu thu thập không chỉ là token GitHub mà còn mở rộng sang thông tin xác thực AWS, Azure, GCP,
.npmrc, khóa SSH, biến môi trường, và cả file cấu hình Claude/MCP
- Thông tin bị đánh cắp sẽ được dùng để tạo và commit vào kho GitHub công khai, phát tán tiếp qua tái phân phối bằng token npm, chèn workflow, đồng thời còn có cơ chế duy trì hiện diện như sửa
~/.bashrc và ~/.zshrc
- Các tổ chức sử dụng Bitwarden CLI cần xử lý sự cố này như một vụ lộ lọt thông tin xác thực và xâm phạm CI/CD, trong đó việc rà soát log CI và thay thế các bí mật có khả năng đã lộ là rất quan trọng
Tổng quan
- Gói npm Bitwarden CLI đã bị xâm phạm như một phần của cuộc tấn công chuỗi cung ứng Checkmarx đang diễn ra, và phiên bản mục tiêu đã được xác nhận là
@bitwarden/cli2026.4.0
- Mã độc nằm trong
bw1.js được nhúng trong gói
- Con đường tấn công phù hợp với dấu hiệu sử dụng GitHub Action bị xâm phạm bên trong pipeline CI/CD của Bitwarden, đồng thời trùng với mẫu chiến dịch đã được xác nhận ở các kho khác
- Phạm vi được xác nhận đến nay chỉ giới hạn ở bản dựng Bitwarden CLI, và việc xâm phạm đi theo vector chuỗi cung ứng GitHub Actions đã được nhận diện trong chiến dịch Checkmarx
- Chỉ gói CLI cho npm có liên quan
- Extension Chrome, máy chủ MCP và các bản phân phối chính thức khác hiện chưa ghi nhận bị ảnh hưởng
- Điều tra vẫn đang tiếp tục, và các phân tích kỹ thuật đầy đủ, phiên bản bị ảnh hưởng, chỉ dấu xâm phạm và hướng dẫn ứng phó sẽ được công bố thêm
- Nếu đang sử dụng Bitwarden CLI, cần rà soát log CI và thay thế các bí mật có khả năng đã bị lộ
Phân tích kỹ thuật
- Payload độc hại
bw1.js chia sẻ hạ tầng cốt lõi với mcpAddon.js của Checkmarx được phân tích ngày hôm trước
- Nó dùng cùng endpoint C2
audit.checkmarx[.]cx/v1/telemetry và được làm rối bằng __decodeScrambled cùng seed 0x3039
- Nó cũng thực hiện rò rỉ dữ liệu dựa trên commit qua GitHub API và đánh cắp token rồi tái phân phối qua npm registry
- Cấu trúc payload nhúng cũng cùng một họ
- Bên trong cấu trúc gzip+base64 có script Python cào bộ nhớ
Runner.Worker của GitHub Actions để nhắm tới token GitHub
- Ngoài ra còn có loader
setup.mjs cho gói npm tái phân phối, workflow YAML của GitHub Actions, khóa công khai RSA hard-code và chuỗi tuyên ngôn mang màu sắc ý thức hệ
- Phạm vi thu thập thông tin xác thực rất rộng
- Token GitHub được lấy từ việc cào bộ nhớ
Runner.Worker và từ biến môi trường
- Thông tin xác thực AWS được tìm trong file
~/.aws/ và trong biến môi trường
- Token Azure được thu qua
azd, còn thông tin xác thực GCP được lấy qua gcloud config config-helper
.npmrc, khóa SSH, biến môi trường và file cấu hình Claude/MCP cũng nằm trong danh sách mục tiêu
- Cách thức rò rỉ qua GitHub cũng đã được xác nhận cụ thể
- Nó tạo kho công khai dưới tài khoản nạn nhân theo quy tắc tên theo chủ đề Dune
{word}-{word}-{3digits}
- Nó commit dữ liệu đã mã hóa và chèn token vào message commit cùng marker
LongLiveTheResistanceAgainstMachines
- Nó còn bao gồm cả cơ chế phát tán qua chuỗi cung ứng
- Với token npm đánh cắp được, nó tìm các gói có quyền ghi để tái phân phối sau khi chèn preinstall hook
- Nó chèn GitHub Actions workflow để tiếp tục thu thập bí mật của kho
- Có công tắc ngắt theo locale Nga
- Nếu locale hệ thống bắt đầu bằng
"ru" thì nó sẽ âm thầm thoát
- Nó kiểm tra
Intl.DateTimeFormat().resolvedOptions().locale và các biến môi trường LC_ALL, LC_MESSAGES, LANGUAGE, LANG
- Runtime là Bun v1.3.13 và được tải từ GitHub Releases
Điểm khác với sự cố Checkmarx
bw1.js chứa thêm các chỉ dấu xâm phạm không có trong tài liệu về sự cố Checkmarx
- Nó hard-code file khóa
/tmp/tmp.987654321.lock để ngăn chạy đồng thời
- Nó chèn payload vào
~/.bashrc và ~/.zshrc để duy trì hiện diện ở shell profile
- Nó dùng branding công khai, như đặt mô tả kho là
Shai-Hulud: The Third Coming và đưa chuỗi debug "Would be executing butlerian jihad!"
- Dù các công cụ dùng chung cho thấy rất rõ mối liên hệ trong cùng một hệ sinh thái mã độc, dấu vết vận hành lại khiến việc quy kết càng khó hơn
- Sau khi bị phát hiện, phía TeamPCP đã tuyên bố nhận trách nhiệm cho vụ tấn công Checkmarx thông qua tài khoản mạng xã hội
@pcpcats
- Mã độc tương ứng khi đó cố ngụy trang bằng phần mô tả trông có vẻ bình thường
- Payload lần này lại thể hiện thái độ công khai khác hẳn
- Các dấu hiệu ý thức hệ như tên kho Shai-Hulud, tuyên ngôn
"Butlerian Jihad", và message commit kêu gọi kháng cự máy móc được nhúng trực tiếp trong mã độc
- Vẫn còn để ngỏ nhiều khả năng: một operator khác dùng chung hạ tầng, một nhánh có màu sắc ý thức hệ mạnh hơn, hoặc sự thay đổi trong thái độ công khai của chính chiến dịch
Khuyến nghị
- Các tổ chức đã cài gói npm Bitwarden độc hại cần coi đây là sự cố lộ lọt thông tin xác thực và xâm phạm CI/CD
- Cần gỡ ngay gói bị ảnh hưởng khỏi hệ thống phát triển và môi trường build, đồng thời thay toàn bộ thông tin xác thực có thể đã lộ trong các môi trường đó
- Bao gồm token GitHub, token npm, thông tin xác thực đám mây, khóa SSH và bí mật CI/CD
- Trên GitHub, cần kiểm tra việc tạo kho trái phép và workflow bất thường
- Cần kiểm tra các file bất ngờ dưới
.github/workflows/, các lần chạy workflow đáng ngờ, việc tải artifact, và các kho công khai theo mẫu tên chủ đề Dune {word}-{word}-{3digits}
- Nếu có khả năng bị ảnh hưởng, hãy kiểm tra các kho mới được tạo với các từ khóa sau
atreides
cogitor
fedaykin
fremen
futar
gesserit
ghola
harkonnen
heighliner
kanly
kralizec
lasgun
laza
melange
mentat
navigator
ornithopter
phibian
powindah
prana
prescient
sandworm
sardaukar
sayyadina
sietch
siridar
slig
stillsuit
thumper
tleilaxu
- Trên npm, cần audit xem có bản phát hành trái phép hay không
- Cần kiểm tra các lần publish không được phê duyệt, thay đổi phiên bản và các install hook mới được thêm vào
- Trong môi trường đám mây, cần rà soát lại log truy cập
- Cần lần theo các truy cập bí mật bất thường, việc sử dụng token và các thông tin xác thực mới được cấp
- Trên endpoint và runner, cần theo dõi hạ tầng rò rỉ và dấu vết truy cập file đã được quan sát
- Cần tìm các kết nối ra ngoài tới
audit[.]checkmarx[.]cx
- Cần kiểm tra xem có thực thi Bun ở môi trường vốn không dùng hay không
- Cần xem xét dấu vết truy cập
.npmrc, .git-credentials, .env, kho lưu thông tin xác thực cloud, gcloud, az, azd
- Cũng cần kiểm tra sự tồn tại của
/tmp/tmp.987654321.lock và việc sửa ~/.bashrc, ~/.zshrc
- Trên GitHub Actions, cần rà soát việc tạo workflow không được phê duyệt
- Cần xác minh workflow có được tạo trong các nhánh tạm hay không
- Cũng cần kiểm tra xem artifact như
format-results.txt có bị tạo hoặc tải xuống hay không
- Về lâu dài, cần giảm bán kính ảnh hưởng của các sự cố chuỗi cung ứng trong tương lai
- Cần thu hẹp phạm vi quyền của token và dùng thông tin xác thực thời hạn ngắn nếu có thể
- Cần hạn chế quyền tạo và phát hành package, đồng thời siết quyền của GitHub Actions
- Cần tắt quyền truy cập artifact không cần thiết và giám sát các kho công khai hoặc thay đổi workflow phát sinh ngoài quy trình phát hành bình thường
Chỉ dấu xâm phạm
-
Gói độc hại
-
Chỉ dấu mạng
-
Chỉ dấu hệ thống tệp
/tmp/tmp.987654321.lock
/tmp/_tmp_<Unix Epoch Timestamp>/
package-updated.tgz
1 bình luận
Ý kiến trên Hacker News
Tôi tự hỏi liệu có biện pháp phòng vệ nào tốt hơn thời gian chờ phát hành tối thiểu hay không
Chỉ cần thêm
min-release-age=7vào.npmrc, có lẽ 334 người đã tránh được việc nhận@bitwarden/cli 2026.4.0, bản được tải lên khoảng 19 giờ trước rồi bị phát hiện là độc hạiCách này cũng khá phù hợp với các vụ như
axios,ua-parser-js,node-ipc; dù không chặn được các trường hợp ẩn mình lâu nhưevent-stream, nó vẫn có vẻ hiệu quả với phần lớn các cuộc tấn công chuỗi cung ứng kiểu bộc phátCó ví dụ cấu hình cách thêm thời gian chờ cho npm/pnpm/bun/uv, và vì không có công cụ một cú nhấp để kiểm tra·áp dụng nên tôi đã tự làm https://depsguard.com
Tôi cũng vừa thấy https://cooldowns.dev, một ý tưởng tương tự
Nó không chỉ đặt thời gian chờ phát hành tối thiểu, mà còn hoạt động như một wrapper bao quanh npm/uv v.v., đối chiếu từng dependency với cơ sở dữ liệu lỗ hổng thương mại trước khi cài đặt để kiểm tra các vấn đề đã biết hoặc tín hiệu đáng ngờ
Ngoài đời thì lúc nào cũng có người cập nhật ngay, nhưng có vẻ chính quá trình lộ diện của những sự cố kiểu này cũng phần nào dựa vào những người cập nhật nhanh
Nếu buộc phải kéo nguyên binary từ registry thì cooldown có thể giảm rủi ro phần nào
Với các trường hợp đuôi dài đã xâm nhập đến cả GitHub, có vẻ cần kết hợp heuristic về commit·maintainer với phân tích thay đổi mã bằng AI, rồi để con người xem xét khi có dấu hiệu bất thường
Nhân tiện tôi làm việc ở đó
Điểm cốt lõi của sự cố lần này là pipeline build đã bị chiếm quyền, khiến package nhiễm độc được phát hành
Dù vậy, nếu bạn đang đặt thứ quan trọng với công việc lên npm, tôi vẫn nghĩ nên pinning dependency
Nhiều lập trình viên cho rằng lockfile là đủ, nhưng nếu vẫn để phạm vi
^thì lúc cập nhật lockfile có thể kéo lên phiên bản mới mà tôi không chọn một cách tường minhNếu đó là hệ thống có thể ảnh hưởng đến sự tồn tại của công ty thì mức phiền phức này là cái giá đáng trả
https://github.com/doy/rbw là phương án thay thế Bitwarden CLI bằng Rust
Hệ sinh thái Rust cũng ngày càng có cảm giác tiến tới cây phụ thuộc lớn và sâu như npm, nhưng ít nhất số tác giả phải tin tưởng vẫn ít hơn nhiều so với trường hợp thường thấy trong JavaScript
Nhưng ít nhất version được pin
rbw + vaultwardenhoạt động khá ổn, như một phiên bản Bitwarden bằng Rust có thể tự hostHoặc theo hướng đưa nhiều tính năng hơn vào thư viện chuẩn của ngôn ngữ
Trải nghiệm với Bitwarden CLI cực kỳ tệ
Tôi chạy
bw listvà tưởng rằng nó chỉ hiện tên mật khẩu, nhưng thực tế nó hiển thị toàn bộ mật khẩu và cả mã TOTP hiện tạiĐiều đáng sợ hơn là khi ssh vào máy chủ rồi mở weechat trong tmux, tôi phát hiện toàn bộ nội dung lệnh
bwcó thể truy cập từ lịch sử nhập của weechatTôi hoàn toàn không hiểu vì sao, nó vẫn còn đó qua cả các phiên tmux và weechat, và chỉ biến mất khi khởi động lại máy chủ
Sau đó tôi xóa ngay
bwCLI và không có ý định cài lạiNhân tiện, terminal tôi dùng là ghostty
Tôi tự hỏi có phải weechat có extension
bwcligì đó không, và đây cũng là lần đầu tôi biết Bitwarden có CLITôi dùng keepass trên máy cục bộ
Tôi không dùng CLI nhưng có dùng plugin trình duyệt
Nếu cái này bị xâm nhập thì đúng là đại họa, nhưng tôi không biết phải làm gì để ngăn chặn
Tôi đang tự hỏi liệu cứ dùng bản cũ đã được kiểm chứng có phải là đáp án không
Bỗng thấy thật kỳ lạ khi phần lớn cuộc sống của mình phụ thuộc vào việc những bí mật này vẫn phải được giữ bí mật
Vì vậy tôi hoàn toàn không dùng extension trình duyệt cho trình quản lý mật khẩu
Từ sau khi từng thấy một sản phẩm có vấn đề bảo mật ở tích hợp trình duyệt, tôi né hẳn; tích hợp trên iOS thì tôi tin hơn tương đối nhưng vẫn cảnh giác
Bao gồm package manager cho phát triển, package manager của OS, extension trình duyệt, và cả tự động cập nhật của ứng dụng độc lập
Các công ty như Socket cần có thời gian để phát hiện cập nhật độc hại, nhưng nếu ai cũng tải về chỉ vài phút sau khi được đăng thì bản thân việc phát hiện như vậy sẽ trở nên vô nghĩa
Tôi rất khuyến nghị cấu hình này
Đọc tiêu đề xong tôi cũng hơi hoảng, nhưng cảm giác là mình đã làm mọi thứ hợp lý có thể làm mà không đến mức hoang tưởng
https://cooldowns.dev
https://depsguard.com
Tôi quản lý cái thứ hai, và nếu biết cái thứ nhất sớm hơn thì chắc đã không cần làm ra nó
Cả hai gần như làm cùng một việc, chỉ là bên tôi dùng Rust nên hơi quá tay một chút
Điều quan trọng nhất ở đây là chỉ cần
npm installlà đã đủNếu điểm xâm nhập là
preinstall, thì quan niệm rằng cứ kiểm tra sau khi cài là được sẽ sụp đổ ngayVì đến thời điểm đó payload đã có cơ hội chạy rồi
Điều này càng thú vị hơn trong môi trường agent, CI, sandbox ngắn hạn, vì dù thời gian lộ diện ngắn, việc cài đặt được lặp lại tự động vẫn là đủ để dính đòn
Một điều nữa đáng chú ý là payload này không chỉ nhắm vào bí mật mà còn nhắm vào cấu hình công cụ AI
Việc sửa shell profile có thể thực tế trở thành con đường làm ô nhiễm ngữ cảnh mà coding assistant tiếp theo sẽ đọc
Tôi đã viết dài hơn về góc nhìn này cùng với công việc AgentSH tại https://www.canyonroad.ai/blog/the-install-was-the-attack/
npm installlà vấn đề đặc biệt thì theo tôi là một lập luận đã bị bác bỏ nhiều lầnĐằng nào rồi bạn cũng sẽ chạy binary thực tế
Và nếu xét cho cùng thì bạn hoàn toàn có thể tự tải package xuống để kiểm tra trước khi cài; nếu bạn không hiểu sâu về đảm bảo hành vi và phạm vi của trình cài đặt, thì việc hời hợt tin tưởng quá trình tải và giải nén mã độc còn kỳ lạ hơn
Kill switch theo locale Nga, nghe vừa táo bạo vừa hèn nhát
Discretion is the better part of valorTóm lại, trông giống kiểu không tự bắn vào chân mình
Trong vụ rò rỉ
Vault7cũng có nội dung nói NSA và CIA cố tình để lại những dấu vết như vậy để làm mờ nguồn gốc, và đây hoàn toàn là kỹ thuật mà các tác nhân quốc gia khác cũng có thể dùngNó trông như dấu vết gây đánh lạc hướng quá lộ liễu, nhưng đồng thời cũng tạo ấn tượng rất mạnh rằng có tác nhân quốc gia can dự
Sống như người dùng KeePass thì bớt hẳn kiểu căng thẳng này
Chỉ riêng 5 năm qua, dùng KeePass trên hạ tầng cục bộ đã giúp tôi tránh được nhiều sự cố bảo mật
Không phải với công cụ truy cập KeePass thì loại vấn đề này là bất khả thi, nên tôi không rõ khác biệt là gì
Tôi vẫn nghĩ là không thể, nhưng thành thật mà nói chưa tìm hiểu kỹ
Ví dụ hai thiết bị đều offline, mỗi bên thêm mật khẩu rồi sau đó online lại thì sẽ xử lý thế nào
Nếu mã hóa bản sao lưu thì mật khẩu mã hóa được lưu ở đâu, rồi mật khẩu của nhà cung cấp cloud lại lưu ở đâu
Điều đặc biệt ấn tượng trong cuộc tấn công lần này là kẻ tấn công phải canh rất chính xác vào lúc GitHub không bị gián đoạn
https://mrshu.github.io/github-statuses/
Vì vậy tôi hoàn toàn không dùng trình quản lý mật khẩu bên thứ ba
Vì như vậy bạn phải liên tục tin rằng họ sẽ làm tốt chuyện bảo mật, cập nhật, sao lưu v.v.
Tôi đã tự làm một trình tạo mật khẩu stateless, nên hoàn toàn không cần sao lưu hay đồng bộ dữ liệu giữa các thiết bị
Chỉ cần nhập một master password rất dài và mạnh cùng tên dịch vụ và username, nó sẽ chạy băm scrypt với tham số phù hợp để việc brute-force gần như bất khả thi
Với các tài khoản quan trọng tôi cũng dùng 2FA