1 điểm bởi GN⁺ 11 giờ trước | 1 bình luận | Chia sẻ qua WhatsApp
  • 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~/.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ựcxâ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 CIthay 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ô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~/.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ựcxâ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

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=7 và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ại
    Cá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át
    Có 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ự

    • Tôi đang dùng Aikido safe-chain
      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ờ
    • Ý tưởng cooldown rất hay, nhưng tôi cũng tự hỏi liệu cuộc tấn công này có thực sự bị chặn nếu không ai cập nhật ngay lập tức hay khô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
    • Tôi nghĩ tốt hơn nên bắt đầu từ việc không đặt backend hay công cụ CLI lên NPM
    • Với cài đặt mới thì là một chuyện, nhưng với dependency hiện có, chẳng phải chỉ cần pin theo patch versioncố định sha là được sao
    • Những cuộc tấn công như thế này thường không xâm nhập đến upstream source, nên nếu làm theo kiểu build từ source như https://www.chainguard.dev/libraries thì có thể chặn khoảng 98%
      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 minh
    Nế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ả

    • Nghĩ theo chiều ngược lại, khi một lỗ hổng bảo mật được vá ở phiên bản sau thì lý tưởng nhất vẫn là hệ thống tự động nhận và áp dụng bản vá đó
  • https://github.com/doy/rbwphươ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ìn vào https://github.com/doy/rbw/blob/main/Cargo.toml#L16 thì bên này cũng có khá nhiều dependency
      Nhưng ít nhất version được pin
    • Tôi tự hỏi dùng trình quản lý mật khẩu tích hợp của Firefox có nhược điểm gì không
    • Mọi người đều xem Rust là an toàn hơn, nhưng dường như lại quá dễ bỏ qua việc rủi ro kéo malware qua dependency đã tăng lên đáng kể
    • Tổ hợp rbw + vaultwarden hoạt động khá ổn, như một phiên bản Bitwarden bằng Rust có thể tự host
    • Vì những chuyện như thế này, tôi nghĩ sẽ có thêm nhiều phần mềm chuyển sang stack kiểu .Net, nơi phần lớn thứ có thể giải quyết mà không cần dependency bên thứ ba
      Hoặ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 list và 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 bw có thể truy cập từ lịch sử nhập của weechat
    Tô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 bw CLI và không có ý định cài lại
    Nhân tiện, terminal tôi dùng là ghostty

    • Cái này gần như chỉ là một lời phàn nàn không liên quan đến chủ đề chính
    • Tôi đã định thử CLI nhưng thấy nó dựa trên JavaScript nên thôi
    • Chuyện này thực sự rất lạ
      Tôi tự hỏi có phải weechat có extension bwcli gì đó không, và đây cũng là lần đầu tôi biết Bitwarden có CLI
      Tô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

    • Càng nhiều điểm tích hợp thì bề mặt tấn công càng lớn
      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
    • Tôi nghĩ cooldown nên trở thành mặc định ở mọi nơi
      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
    • Hai tài sản số quý giá nhất của tôi là email và tài khoản Bitwarden luôn được bảo vệ bằng một Yubikey tôi mang theo bên người và một khóa dự phòng đặt ở nơi khác
      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
    • Bạn có thể dùng app desktop hoặc web vault trực tiếp thay vì plugin trình duyệt
    • Cách ngăn chặn, nói ngắn gọn, là hai thứ này
      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 install là đã đủ
    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 đổ ngay
    Vì đế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/

    • Thực ra chẳng ai kiểm tra package sau khi cài, và việc chỉ xem script npm install là 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

    • Tệ hơn nữa là ta còn không biết đó là dấu vết thật hay chỉ là false flag
    • Tôi nghĩ đến đủ loại châm ngôn như Discretion is the better part of valor
      Tóm lại, trông giống kiểu không tự bắn vào chân mình
    • Bản thân nó không phải bằng chứng quyết định
      Trong vụ rò rỉ Vault7 cũ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ùng
    • Nó cũng giống như một chiến dịch đe dọa do nước khác thực hiện
    • Trong tác vụ GitHub CI để npm publish, ai lại đi chỉnh locale như thế chứ
      Nó 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

    • Vụ này vấn đề nằm ở công cụ truy cập chứ không phải bản thân vault
      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 cần truy cập mật khẩu cả từ hạ tầng lẫn điện thoại, không rõ với KeePass thì giải quyết chuyện đó thế nào
      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ỹ
    • Có thể tốt với người tự vận hành được hạ tầng, nhưng khó mà áp dụng cách nói stress free đó cho người dùng trung bình
    • Tôi hiểu mô hình một file duy nhất, nhưng thực tế đồng bộ và xử lý xung đột làm sao
      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
    • Điều tôi vẫn chưa thông ở KeePass là sao lưu đám mây
      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

  • 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