Bảo mật & quyền riêng tư

Lỗ hổng bộ giải mã Brotli trong Node.js cho phép thực thi mã từ xa trên các bản build chính thức

Các nhà nghiên cứu của Imperva đã chứng minh khả năng thực thi mã từ xa thông qua dữ liệu Brotli được tạo đặc biệt trong Node.js 24.22.0. Các bản vá có sẵn cho những phiên bản được hỗ trợ, đòi hỏi phải cập nhật ngay lập tức đối với các dịch vụ giải mã dữ liệu

Minh họa một luồng dữ liệu nén bị hỏng rò rỉ mã độc
Minh họa được tạo riêng cho bài viết này

Được dịch tự động từ bản gốc tiếng Anh.

Các nhà nghiên cứu bảo mật tại Imperva đã chứng minh một lỗ hổng nghiêm trọng cho phép thực thi mã từ xa (RCE) trong môi trường runtime Node.js chính thức. Bằng cách cung cấp dữ liệu nén Brotli được tạo đặc biệt cho bộ giải mã đi kèm, họ đã thành công trong việc thực thi mã tùy ý trên bản build Linux arm64 chuẩn của Node.js 24.22.0. Nhóm phát triển Node.js đã công bố lỗ hổng này, được theo dõi dưới mã CVE-2026-111497, và phát hành các bản sửa lỗi vào ngày 21 tháng 10, kêu gọi các nhà phát triển cập nhật bất kỳ ứng dụng nào xử lý luồng dữ liệu Brotli không đáng tin cậy.

Chuyện gì đã xảy ra

Buổi trình diễn, được đặt tên là "Node2Shell", đánh dấu một bước leo thang đáng kể so với các nỗ lực chứng minh khái niệm (proof-of-concept) trước đó. Các nhà nghiên cứu trước đây chỉ đạt được khả năng thực thi mã trên các bản build thử nghiệm bị cố tình làm suy yếu, trong khi các bản build tiêu chuẩn chỉ bị crash hoặc cho phép đọc bộ nhớ hạn chế. Tuy nhiên, nhóm của Imperva đã chạy khai thác mã độc của họ trên hình ảnh Docker Node.js 24.22.0 chính thức mà không sử dụng trình gỡ lỗi hay các chỉnh sửa tùy biến. Mặc dù cuộc tấn công không mang tính xác định và cần nhiều lần thử để thành công trong môi trường Linux arm64 của họ, nó đã xác nhận rằng việc thực thi mã đầy đủ là khả thi trên các thiết lập cấp độ sản xuất.

Lỗ hổng này ảnh hưởng đến một phạm vi rộng lớn các ứng dụng vì nó nằm trong bộ giải mã Brotli được đóng gói cùng với chính Node.js. Nó tác động đến các dòng phát hành đang hoạt động 22.x, 24.x và 26.x. Rủi ro tồn tại bất cứ khi nào một ứng dụng giải mã dữ liệu đã nén bằng Brotli, điều này có thể xảy ra theo hai cách chính: khi đọc phản hồi đã nén thông qua API fetch() tích hợp sẵn, hoặc khi middleware giải mã tường minh phần thân yêu cầu đã nén. Ví dụ, các trình phân tích body của Express 5 hiện nay xử lý Brotli bên cạnh gzip và deflate, nghĩa là nhiều dịch vụ backend hiện đại bị phơi nhiễm nếu chúng xử lý các yêu cầu đầu vào từ nguồn không đáng tin cậy.

Imperva đã kiểm thử vector tấn công này bằng cách sử dụng Express 5.0.0 đến 5.3.0 và body-parser 2.0.0 đến 2.3.0, tái hiện việc thực thi mã thông qua cả đường dẫn yêu cầu và phản hồi. Một máy chủ HTTP Node.js thuần túy không dễ bị tổn thương theo mặc định trừ khi nó sử dụng middleware hoặc các lệnh gọi tường minh để giải mã phần thân. Tính đến ngày 22 tháng 10, chưa có báo cáo về việc khai thác tích cực trong thực tế, nhưng sự sẵn có của một proof of concept hoạt động được trên các bản build chính thức làm tăng mức độ khẩn cấp cho việc vá lỗi.

Cách thức hoạt động

Nguyên nhân gốc rễ nằm ở cách bộ giải mã Brotli đi kèm xử lý các chuyển đổi trạng thái không hợp lệ trong một luồng nén. Một luồng Brotli thông báo các loại khối mà nó sẽ sử dụng khi quá trình giải mã tiến triển. Trong đầu vào độc hại do Imperva tạo ra, luồng đã đạt đến một thay đổi khối mà cấu trúc của chính nó đã loại trừ rõ ràng là không thể xảy ra. Thay vì từ chối mâu thuẫn này, bộ giải mã dễ bị tổn thương đã diễn giải nó như một yêu cầu thêm dữ liệu đầu vào và tiếp tục xử lý trong một trạng thái không hợp lệ.

Khi bộ giải mã tiếp tục trong trạng thái bị hỏng này, nó thất bại trong việc thực thi các kiểm tra biên giới phù hợp. Các bài kiểm thử sử dụng bộ thanh lọc bộ nhớ (memory sanitizer) tiết lộ rằng lỗi logic này dẫn đến một thao tác ghi ngoài phạm vi (out-of-bounds write), nơi dữ liệu được ghi vượt quá giới hạn bộ đệm dự kiến. Sự hư hỏng bộ nhớ này tạo cơ hội cho kẻ tấn công chèn và thực thi mã. Dự án Node.js đã giải quyết vấn đề bằng cách nhập một bản vá từ thư viện Brotli upstream. Bản sửa lỗi này đảm bảo bộ giải mã dừng ngay lập tức và trả về lỗi định dạng khi gặp các mâu thuẫn cấu trúc không thể xảy ra, ngăn chặn trạng thái không hợp lệ xuất hiện.

Chi tiết quan trọng

  • ID Lỗ hổng: CVE-2026-111497 ảnh hưởng đến bộ giải mã Brotli đi kèm trong Node.js.
  • Phiên bản bị ảnh hưởng: Các dòng phát hành đang hoạt động 22.x, 24.x và 26.x bị tổn thương; các phiên bản đã hết vòng đời (end-of-life) như 20.x không nhận được bản sửa lỗi.
  • Vector tấn công: Dữ liệu Brotli được tạo đặc biệt gửi qua phần thân yêu cầu HTTP (được giải mã bởi middleware) hoặc nhận được qua phản hồi của fetch().
  • Độ tin cậy của khai thác: Proof of concept của Imperva yêu cầu nhiều lần thử để thành công trên Linux arm64 và chưa được kiểm thử trên các kiến trúc khác.
  • Trạng thái sửa lỗi: Các bản vá đã được phát hành vào ngày 21 tháng 10; phiên bản 24.22.1 an toàn từ chối dữ liệu độc hại.
  • Không có giải pháp tạm thời ở runtime: Thông báo tư vấn nêu rõ không có thay đổi cấu hình nào trong Node.js để giảm thiểu rủi ro này; việc cập nhật là biện pháp khắc phục duy nhất.

Tại sao điều này quan trọng

Đối với các kỹ sư phần mềm và trưởng nhóm kỹ thuật, lỗ hổng này làm nổi bật một rủi ro ẩn trong chuỗi phụ thuộc. Vì lỗi nằm trong chính runtime chứ không phải trong một gói npm của bên thứ ba, các công cụ kiểm kê gói tiêu chuẩn có thể không cảnh báo về nó. Các nhà phát triển thường giả định rằng các thư viện nén là những tiện ích cấp thấp an toàn, nhưng sự cố này chứng minh rằng chúng có thể là con đường trực tiếp dẫn đến thực thi mã từ xa. Các dịch vụ proxy API bên ngoài hoặc chấp nhận tải lên của người dùng đặc biệt có nguy cơ nếu chúng tự động giải nén nội dung mà không có xác thực chặt chẽ.

Việc thiếu giải pháp tạm thời ở runtime có nghĩa là các đội vận hành không thể đơn giản bật/tắt một feature flag để giữ an toàn. Nếu hạ tầng của bạn dựa trên các container image hoặc artifact dựng sẵn, bạn phải đảm bảo binary Node.js cơ sở được cập nhật. Điều này thường đòi hỏi phải xây dựng lại và triển khai lại các dịch vụ, chứ không chỉ khởi động lại chúng. Hơn nữa, các nền tảng như Vercel đã thêm các quy tắc tường lửa ứng dụng web (WAF) để chặn các cuộc tấn công inbound, nhưng chúng không bảo vệ chống lại các phản hồi Brotli độc hại được server của bạn fetch từ các host khác, khiến đường outbound vẫn dễ bị tổn thương cho đến khi được vá.

Bạn có thể làm gì

  • Nâng cấp tất cả các instance Node.js lên các phiên bản đã vá mới nhất trong các dòng 22.x, 24.x hoặc 26.x ngay lập tức.
  • Kiểm toán các container image và pipeline CI/CD của bạn để đảm bảo binary Node.js cơ sở được cập nhật, không chỉ mã ứng dụng.
  • Xác định các dịch vụ sử dụng Express 5 hoặc body-parser chấp nhận phần thân yêu cầu không đáng tin cậy và ưu tiên vá lỗi cho chúng.
  • Xem xét việc sử dụng API fetch() tích hợp sẵn để đảm bảo các phản hồi từ máy chủ bên ngoài không đáng tin cậy được xử lý thận trọng.
  • Di chuyển bất kỳ ứng dụng nào vẫn chạy trên các phiên bản đã hết vòng đời như 20.x sang một dòng phát hành được hỗ trợ để nhận các bản sửa lỗi bảo mật.
  • Giám sát nhật ký để tìm các crash bất thường hoặc lỗi bộ nhớ trong các dịch vụ xử lý dữ liệu nén, điều này có thể chỉ ra các nỗ lực khai thác.
  • #nodejs
  • #security
  • #vulnerability
  • #brotli
  • #backend

Công cụ từ cửa hàng Bytechap

Đọc tiếp

Tất cả bài viết