17 điểm bởi GN⁺ 2025-11-25 | 5 bình luận | Chia sẻ qua WhatsApp
  • Hơn 1.000 thành phần trên registry NPM đã bị nhiễm theo cùng một cách chỉ trong vài giờ, và các phiên bản mới chứa mã độc đã được phát hành
  • Các gói độc hại ngụy trang thành script cài đặt Bun runtime, thêm setup_bun.jsbun_environment.js đã bị làm rối mã; khi chạy sẽ dùng TruffleHog để đánh cắp thông tin xác thực cục bộ
  • Thông tin nhạy cảm thu thập được như token AWS/GCP/Azure·GitHub·NPM được gửi ra ngoài thông qua runner GitHub Actions có tên SHA1HULUD
  • Script độc hại tự động chạy npm publish để tự nhân bản theo kiểu sâu máy tính, khiến hơn 27.000 kho GitHub bị nhiễm
  • Đây được đánh giá là một ví dụ nữa làm nổi bật mối đe dọa an ninh chuỗi cung ứng trên toàn bộ hệ sinh thái mã nguồn mở

Tổng quan cuộc tấn công

  • Ngày 24 tháng 11 năm 2025, HelixGuard phát hiện hơn 1.000 gói trên registry NPM bị nhiễm theo cùng một thủ đoạn trong vòng vài giờ
    • Các phiên bản mới ngụy trang như thể bổ sung Bun runtime và chứa script preinstall: node setup_bun.js
    • Tệp bun_environment.js được phát hành kèm theo là mã độc đã bị làm rối; khi thực thi sẽ tải xuống và chạy TruffleHog
  • TruffleHog quét và đánh cắp token NPM, thông tin xác thực AWS/GCP/Azure, biến môi trường từ môi trường cục bộ
  • Dữ liệu bị đánh cắp được rò rỉ ra ngoài thông qua việc tạo runner GitHub Actions SHA1HULUD và một kho GitHub có mô tả Sha1-Hulud: The Second Coming.
  • HelixGuard cho rằng cuộc tấn công này có thể do cùng tác nhân đứng sau vụ “Shai-Hulud” xảy ra vào tháng 9 năm 2025

Phân tích cách mã độc hoạt động

  • Ví dụ khi phân tích gói @asyncapi/specs, phiên bản phát hành trên NPM đã bị nhiễm, trong khi kho nguồn gốc trên GitHub vẫn an toàn
  • Kẻ tấn công sửa package.json để thêm setup_bun.js, rồi cấu hình script này gọi bun_environment.js
  • bun_environment.jstệp JavaScript bị làm rối mã ở mức cao với kích thước hơn 10MB, có các chức năng chính sau
    • Thu thập thông tin xác thực đám mây và token từ biến môi trường
    • Quét secret bằng TruffleHog
    • Rò rỉ dữ liệu qua GitHub Actions
  • Ngoài ra, nó còn sửa package.json để chèn mã lây nhiễm và tự động chạy npm publish, từ đó phát tán theo kiểu sâu máy tính

Lây nhiễm GitHub và rò rỉ dữ liệu

  • Script độc hại tạo tệp .github/workflows/formatter_123456789.yml và đăng ký runner SHA1HULUD
  • Workflow này đóng gói secret của kho vào tệp actionsSecrets.json đã được mã hóa Base64 hai lớp
  • Sau đó, nó tạo một kho GitHub có tên ngẫu nhiên với mô tả Sha1-Hulud: The Second Coming. để tải dữ liệu lên
  • HelixGuard xác nhận hơn 27.000 kho GitHub đã bị nhiễm
  • Các thông tin bí mật bị đánh cắp bao gồm thông tin xác thực của nhiều dịch vụ như AWS_ACCESS_KEY_ID, SLACK_WEBHOOK_URL, CODECOV_TOKEN, WEBFLOW_TOKEN

Danh sách gói bị nhiễm

  • HelixGuard báo cáo hàng trăm gói NPM đã bị nhiễm
    • Tiêu biểu có các gói từ những tổ chức lớn như @asyncapi, @ensdomains, @posthog, @zapier, @postman, @voiceflow
    • Mỗi gói có nhiều phiên bản bị nhiễm, ví dụ @asyncapi/specs@6.8.2, @postman/csv-parse@4.0.5
  • Phần lớn các gói bị nhiễm đều giả dạng dự án mã nguồn mở hợp pháp, với mã độc được chèn vào trong quy trình phát hành tự động

Hàm ý về bảo mật

  • Cuộc tấn công lần này là một ví dụ về việc lợi dụng lỗ hổng an ninh chuỗi cung ứng để lây nhiễm quy mô lớn trong hệ sinh thái mã nguồn mở
  • Nó cho thấy sự cần thiết phải tăng cường quản trị an ninh trên toàn bộ hạ tầng phát triển, bao gồm NPM, GitHub và thông tin xác thực đám mây
  • HelixGuard khuyến nghị ngừng cài đặt ngay các gói bị nhiễm, đồng thời thu hồi ngay lập tức các token và thông tin xác thực liên quan

5 bình luận

 
developerjhp 2025-11-25

Mình đã thử tạo một script scanner theo thời gian thực.

Tại path của repository bị nghi ngờ,
chỉ cần nhập npx sha1-hulud-scanner là được.

Mã nguồn: https://github.com/developerjhp/sha1-hulud-scanner

 
ahwjdekf 2025-11-27

Hệ sinh thái js đúng là một bãi rác hỗn loạn.

 
GN⁺ 2025-11-25
Ý kiến trên Hacker News
  • Chia sẻ một mẹo: nên dùng PNPM thay vì NPM
    PNPM 10.x chặn được nhiều vector tấn công
    1️⃣ Mặc định không chạy script post-install, cần phê duyệt thủ công
    2️⃣ Có thể cấu hình chỉ cho cài đặt sau một khoảng thời gian nhất định kể từ khi bản phát hành mới được tung ra (ví dụ: 4 ngày)
    NPM quá bấp bênh trong môi trường CLI production
    Nên giới hạn publisher key theo nguyên tắc đặc quyền tối thiểu, chỉ bind với các package cụ thể, và ràng buộc IP vào CI/CD runner
    Đừng để publish key ở máy local; nếu cần thì hãy cân nhắc OIDC Trusted Publisher hoặc truy cập dựa trên token

    • NPM giống như một sản phẩm chất đầy nợ kỹ thuật
      Chỉ riêng lockfile thôi cũng đã thử đến năm lần mà vẫn chưa hoàn hảo
      Nhìn vào cấu trúc và lịch sử commit thì thấy team đang rất cố cải thiện, nhưng có cảm giác họ bắt đầu từ một cái hố quá sâu
      Nó vẫn không phát hiện được EOF sớm trong lúc truyền file, và còn để lại file không hoàn chỉnh trong cache, khiến môi trường Internet chậm rất dễ lãng phí thời gian vì cập nhật thất bại
    • Tôi thích cách quản lý bí mật động của HashiCorp Vault / OpenBao hơn
      Ban đầu hơi phức tạp, nhưng có thể quản lý bí mật theo khái niệm lease
      Mỗi bản build CI tạo một lease và tự hủy khi kết thúc, đồng thời hỗ trợ TTL và tự động xoay vòng
      Nhờ vậy có thể tránh dùng credential dài hạn và chỉ cấp token sống ngắn đúng vào thời điểm build
      Điểm tích cực là các cuộc tấn công kiểu này thực sự thúc đẩy thảo luận bảo mật trong công ty
    • Chỉ cần dùng npm ci là được
      Nó chỉ cài các phiên bản được chỉ định trong package-lock.json, nên có thể giảm rủi ro bị tấn công do tự động cập nhật
      Điều quan trọng là giữ thói quen chỉ cập nhật khi chủ động muốn cập nhật
    • Trong hệ sinh thái Python, có thể đạt được mức bảo vệ tương tự bằng tùy chọn pip install --only-binary=:all:
      Nó chặn hoàn toàn source distribution và chỉ cài wheel
      Tuy vậy có thể phát sinh ràng buộc về phiên bản
      Trong uv, có thể dùng tùy chọn --exclude-newer để mô phỏng tính năng “thời gian phát hành tối thiểu” của PNPM
    • Gần đây tôi đọc một bài về “dependency cooldown” và rất đồng cảm
      Tôi cố định toàn bộ dependency và xem xét thủ công các cảnh báo từ dependabot
      Tôi vẫn còn băn khoăn không biết như vậy là quá tay hay là thói quen đúng đắn
  • Hôm nay có một bài đặc biệt liên quan: “We should all be using dependency cooldowns”
    Tự động cập nhật dependency có thể còn nguy hiểm hơn cả lỗ hổng chỉ tồn tại trong một ngày
    Việc hoàn tác một package đã nhiễm độc đã lan vào hàng nghìn lockfile còn khó hơn nhiều

    • Tôi nghĩ tốt hơn là chỉ cập nhật khi thực sự cần
      Nếu mọi thứ đang chạy ổn thì không có lý do gì phải động vào
    • Nhưng làm vậy thì vẫn cần người khác sửa bug cho mình, và nếu ai cũng dùng cooldown thì rốt cuộc có thể chỉ dậm chân tại chỗ
    • Trong uv của Python, có thể tạo hiệu ứng tương tự bằng lệnh uv lock --exclude-newer $(date --iso -d "24 hours ago")
      Thảo luận liên quan nằm ở issue #14992
    • Với npm-check-updates cũng làm rất đơn giản được
      Lệnh npx npm-check-updates -c 7 có thể đặt cooldown 7 ngày
      Xem tài liệu npm-check-updates
    • Tôi không đồng ý với lập luận này
      Cooldown có thể kéo dài thời gian phát tán của lỗ hổng 0-day
      Nếu ai cũng dùng cùng một cooldown thì chỉ tạo ra độ trễ trong phát hiện mà thôi
  • Tôi là đồng sáng lập PostHog
    Chúng tôi là một trong các nạn nhân của đợt tấn công này
    Các phiên bản bị nhiễm là posthog-node 4.18.1, 5.13.3, 5.11.3 / posthog-js 1.297.3 / posthog-react-native 4.11.1 / posthog-docusaurus 2.0.6
    Chúng tôi đã thay toàn bộ key và mật khẩu, đồng thời phát hành phiên bản mới
    Hiện đang phân tích nguyên nhân và sẽ cập nhật trên status.posthog.com

    • Tôi khuyến nghị nên cấu hình cảnh báo nếu một package release mới không gắn với một lần chạy CI/CD
    • Tôi tò mò không biết JS bị nhiễm có thực sự ảnh hưởng đến người dùng cuối hay không
      Nếu website đã triển khai phiên bản bị nhiễm, tôi muốn biết khách truy cập có bị ảnh hưởng không
    • Nếu chưa biết nguyên nhân thì vẫn có khả năng cuộc tấn công đang tiếp tục lan rộng
    • Phiên bản mới nhất cũng có thể lại bị nhiễm, vậy tại sao lần này mọi người phải tin?
    • May là cập nhật ở đây dễ thấy hơn thông báo trên Twitter. Mong mọi việc khôi phục suôn sẻ
  • Câu hỏi nghiêm túc: có nên bắt đầu dự án mới bằng Node không
    Tôi đang làm frontend SaaS bằng Astro và cứ mỗi lần cập nhật dependency lại thấy bất an
    Cảm giác như sự thiếu an toàn của hệ sinh thái npm là quá nghiêm trọng

    • Vấn đề không nằm ở Node hay JS mà ở mô hình đóng gói package
      Các hệ sinh thái phụ thuộc vào vô số subpackage như Rust rồi cũng sẽ gặp chuyện tương tự thôi
      Việc không có package manager như C, C++, Odin đôi khi còn có thể là lựa chọn khôn ngoan hơn về mặt bảo mật
    • Tôi nghĩ đây là vấn đề của bản thân npm hơn là của Node
      Gần đây tôi tin tưởng JSR của Deno hơn
      Các package dựa trên JSR cũng được phát hành chéo sang npm, và cũng có package chỉ dành cho Deno
      Ví dụ Lume là một SSG chậm nhưng ổn định, tạo ấn tượng khá tốt với tôi
    • Đây không phải vấn đề riêng của Node
      Chỉ là npm là kho lớn nhất nên với kẻ tấn công thì đáng giá hơn mà thôi
      RubyGems hay Cargo cũng hoàn toàn có thể gặp chuyện tương tự
    • Quan điểm phải tránh Node là hơi quá
      Chỉ vì đây là hệ sinh thái được dùng nhiều nhất nên bị nhắm tới nhiều hơn thôi
      Chỉ cần quản lý dependency cẩn thận và đừng cập nhật mỗi ngày
    • Chúng tôi xây dựng nền tảng phân tích bảo mật sản phẩm bằng PHP
      Điểm hay là không cần hơn 100 dependency chỉ để render một trang
      Xem liên kết dự án
  • Dạo này tôi chỉ phát triển bên trong container Podman
    Mọi đoạn mã chưa đọc qua đều phải chạy trong môi trường cô lập
    Không hoàn hảo, nhưng tôi xem đó là thói quen bảo mật tối thiểu

    • Hầu hết mọi người thấy 99,99% trường hợp đều không sao nên dần chai lì với rủi ro
      Bảo mật thường là lĩnh vực ủy quyền cho chuyên gia, nên trên thực tế rất khó thay đổi
    • Cây dependency của npm quá sâu, nên tôi tò mò không biết cách cô lập bằng container hoạt động ra sao trong trường hợp này
    • Tôi muốn biết cụ thể cách xử lý các package npm như PostHog SDK bên trong container
    • Podman an toàn hơn Docker, và nếu cần còn có thể cân nhắc thêm lớp cô lập như QEMU
    • Tôi thì SSH sang hẳn một user local khác rồi dùng tmux để phát triển
  • 12 năm trước NPM từng sập hoàn toàn một lần
    Hồi đó nó chỉ là một dự án mã nguồn mở đơn thuần, còn giờ thuộc sở hữu của Microsoft
    Nếu là một trong những công ty lớn nhất thế giới thì chẳng phải họ nên giải quyết các vấn đề kiểu này sao?
    Nhưng đến giờ vẫn chẳng thấy thay đổi bao nhiêu

    • MS còn quản lý Windows chưa ra hồn
      Cái gì không kiếm được tiền từ license doanh nghiệp thì họ bỏ mặc
      Vì thế Windows 11 giống một cỗ máy marketing hơn
  • Chúng tôi hiện đang theo dõi hoạt động tấn công và cập nhật danh sách package bị nhiễm trên blog của Wiz
    Chúng tôi đang reverse engineering payload độc hại và dự kiến sẽ chia sẻ kết quả trong vài giờ tới

  • Phần chat “Talk to a human” của PostHog hóa ra lại là phản hồi của bot, khá khó chịu
    Ngay cả liên kết hỗ trợ khẩn cấp cũng không được chỉ dẫn rõ ràng
    Vì vậy tôi muốn hỏi — nên tránh những phiên bản nào?

    • Tôi là đồng sáng lập. Tôi đã thông báo ở thread chính và trên status.posthog.com
      Các phiên bản bị nhiễm là posthog-node 4.18.1, 5.13.3, 5.11.3 / posthog-js 1.297.3 / posthog-react-native 4.11.1 / posthog-docusaurus 2.0.6
      Chỉ cần cập nhật lên phiên bản mới nhất là an toàn
    • Tôi cũng đã nhận được cùng danh sách phiên bản đó trong kênh Slack
  • Tôi không hiểu vì sao những vụ hỗn loạn package kiểu này lúc nào cũng xảy ra trong hệ sinh thái Node
    Không hiểu tại sao cộng đồng này lại tin rằng các install hook phức tạp và cập nhật tự động là kỹ thuật tốt
    Tôi hiểu vì sao người tạo ra Node đã rời đi rồi

    • Node giống PHP mới
      Hệ sinh thái khổng lồ, thiên về lập trình viên mới, ý thức bảo mật kém, và ngay cả chức năng nhỏ cũng phụ thuộc thư viện
    • Một hệ sinh thái nghiêm túc thì phải có maintainer package
      Phải có người quản lý đáng tin cậy xác minh như Debian, nhưng cộng đồng JS lại từ chối điều đó và gọi là gatekeeping
      Vì vậy những chuyện thế này cứ lặp đi lặp lại
    • Hạ thấp người khác để thấy mình vượt trội chỉ mang lại cảm giác nhất thời
      Với thái độ đó thì chẳng có gì thay đổi được
  • Hơi lạc đề một chút, nhưng tôi tò mò HelixGuard là ai
    Website của họ khá tệ và gần như không có thông tin gì
    Nghe nói khách hàng là các sàn giao dịch crypto nên thấy hơi đáng ngờ

 
laeyoung 2025-11-25

2️⃣ Có thể thiết lập để chỉ được cài đặt sau khi đã qua một khoảng thời gian nhất định (ví dụ: 4 ngày) kể từ khi bản phát hành mới được triển khai

Đúng là một tính năng quá hay. Google cũng thỉnh thoảng đưa lên NPM những phiên bản bị lỗi không chạy được, nên có lúc tôi còn hoang mang không biết là do lỗi của mình nữa.