Nội dung bài viết
Ngày 21/10/2026, dự án Node.js phát hành bản cập nhật bảo mật cho cả ba dòng đang được hỗ trợ, vá 10 lỗ hổng. Bốn lỗ hổng ở mức cao (high), trong đó đáng chú ý nhất là lỗi ghi ngoài vùng nhớ trong bộ giải nén Brotli mà Node.js cho biết có thể dẫn tới thực thi mã từ xa (RCE).
| Dòng phiên bản | Bản vá | Số CVE ảnh hưởng |
|---|---|---|
| Node.js 26.x | 26.12.1 | 10 |
| Node.js 24.x (LTS) | 24.22.1 | 8 |
| Node.js 22.x | 22.23.4 | 7 |
Hiện chưa có thông tin về việc các lỗ hổng này bị khai thác ngoài thực tế. Node.js nhắc lại rằng các phiên bản đã hết hỗ trợ (EOL), như 20.x trở về trước, luôn bị ảnh hưởng mỗi khi có bản vá bảo mật nhưng sẽ không được vá.
4 lỗ hổng mức cao
CVE-2026-111497 - Lỗi ghi ngoài vùng nhớ trong bộ giải nén Brotli (cả 3 dòng)
Brotli là thuật toán nén phổ biến trên web; trình duyệt và máy chủ thường dùng nó qua header Content-Encoding: br. Lỗi nằm trong thư viện Brotli được đóng gói sẵn trong Node.js và được sửa bằng một bản vá lấy từ dự án Brotli gốc. Theo Node.js, lỗi cho phép ghi ngoài vùng nhớ, có thể dẫn tới thực thi mã từ xa.
Node.js chưa công bố chi tiết kỹ thuật. Nhóm có nguy cơ cao nhất là các ứng dụng giải nén dữ liệu Brotli từ nguồn không tin cậy, ví dụ dùng module zlib (brotliDecompress, createBrotliDecompress) với dữ liệu người dùng gửi lên, hoặc tải nội dung từ máy chủ bên ngoài có nén Brotli.
CVE-2026-106069 - Vượt kiểm tra hostname chứng chỉ TLS khi host "được hiểu lỏng" thành địa chỉ IP (cả 3 dòng)
CVE-2026-105483 - Vượt kiểm tra hostname TLS khi IP được viết bằng chữ số toàn độ rộng (26.x, 24.x)
Hai lỗi này liên quan tới cách Node.js chuẩn hóa địa chỉ IP khi đối chiếu với chứng chỉ TLS. Chữ số toàn độ rộng (fullwidth) là dạng chữ số Unicode như 127, nhìn giống 127 nhưng khác mã ký tự. Bản vá khiến Node.js từ chối các địa chỉ IP viết ở dạng không chuẩn. Riêng CVE-2026-105483 là lỗi tái phát (regression) trong phần chuẩn hóa IP. Hậu quả là kết nối HTTPS có thể chấp nhận chứng chỉ không đúng với máy chủ thật - điều kiện cho tấn công nghe lén hoặc giả mạo máy chủ.
CVE-2026-105482 - dns.resolve cắt ngắn tên miền chứa ký tự NUL (cả 3 dòng)
Tên miền chứa ký tự NUL (\0) bị cắt ngắn khi phân giải, nên Node.js có thể phân giải một tên miền khác với tên mà ứng dụng đã kiểm tra. Ứng dụng dùng danh sách cho phép tên miền (allowlist), ví dụ để chống tấn công SSRF, có thể bị vượt qua theo cách này. Bản vá bổ sung kiểm tra ký tự NUL trong đầu vào của dns.resolve.
Các lỗ hổng mức trung bình và thấp
| CVE | Mức | Dòng bị ảnh hưởng | Nội dung |
|---|---|---|---|
| CVE-2026-105481 | Trung bình | 26, 24, 22 | Socket keep-alive xử lý một phản hồi được gửi tới trước khi request được gửi đi |
| CVE-2026-106072 | Trung bình | 26, 24, 22 | Hostname IPv4 dạng không chuẩn khiến tên miền trong chứng chỉ (DNS SAN) được dùng để xác thực một địa chỉ IP |
| CVE-2026-106074 | Trung bình | 26, 24, 22 | Bộ đệm số ngẫu nhiên của crypto.randomUUID() và randomInt() bị lưu vào startup snapshot và ứng dụng đóng gói một file (SEA), nên mọi tiến trình sinh ra cùng một dãy giá trị |
| CVE-2026-106070 | Thấp | 26 | ZipFile trả về dữ liệu do kẻ tấn công kiểm soát sau khi kiểm tra header ZIP thất bại |
| CVE-2026-106071 | Thấp | 26 | Permission Model cấp quyền hệ thống file rộng hơn mức cho phép khi dùng ký tự đại diện |
| CVE-2026-106073 | Thấp | 26, 24, 22 | Vượt Permission Model qua fs.realpathSync |
Đáng chú ý là CVE-2026-106074: ứng dụng dùng startup snapshot hoặc đóng gói dạng SEA và dựa vào randomUUID() để tạo mã định danh, token... có thể sinh ra giá trị trùng lặp, đoán trước được giữa các lần khởi động.
Cập nhật thư viện đi kèm và chứng chỉ gốc
Bản phát hành còn cập nhật các thư viện đi kèm để vá lỗ hổng đã công bố:
- undici (nền tảng của
fetch()trong Node.js) - cả 3 dòng - c-ares 1.34.9 (phân giải DNS) - cả 3 dòng
- OpenSSL 3.5.9 - dòng 24.x và 22.x
- SQLite 3.53.4 - dòng 22.x
Node.js cũng cập nhật kho chứng chỉ gốc lên NSS 3.131.1 để xử lý sự cố eMudhra: 8 CA trung gian của eMudhra bị lộ khóa riêng và đã bị các trình duyệt chặn. Dòng 26.x và 24.x có thêm cơ chế từ chối chuỗi chứng chỉ chứa khóa công khai nằm trong danh sách chặn. Nếu ứng dụng có fetch() hoặc https.request() tới máy chủ dùng chứng chỉ từ các CA này, kết nối sẽ bị từ chối sau khi cập nhật.
Cần làm gì?
- Kiểm tra phiên bản đang chạy bằng
node -v, rồi cập nhật lên 26.12.1, 24.22.1 hoặc 22.23.4. - Nếu dùng Docker, cập nhật image gốc (ví dụ
node:24) rồi build lại và triển khai lại container. Kéo image mới về mà không build lại thì ứng dụng vẫn chạy bản cũ. - Kiểm tra cả các nơi Node.js được cài riêng: máy chủ CI/CD, môi trường serverless, công cụ build... Nhiều nhà cung cấp hosting và serverless cập nhật runtime theo lịch riêng, nên cần xem thông báo của từng nhà cung cấp.
- Nếu còn chạy Node.js 20.x trở về trước, đây là lúc lên kế hoạch nâng cấp: các bản này đã hết hỗ trợ và sẽ không nhận bản vá cho những lỗi trên.
- Ứng dụng dùng startup snapshot hoặc SEA nên đóng gói lại sau khi cập nhật để bỏ dãy số ngẫu nhiên đã bị lưu sẵn.
Nguồn tham khảo: Node.js - October 21, 2026 Security Releases và ghi chú phát hành v26.12.1, v24.22.1, v22.23.4.