- Một lỗ hổng bảo mật cho phép thực thi mã từ xa (RCE) đã được báo cáo trong React và Next.js
- Vấn đề này phát sinh bên trong gói Next.js, và kẻ tấn công có thể lợi dụng đầu vào độc hại để dẫn đến thực thi mã tùy ý
- Vercel đã công bố lỗ hổng này thông qua khuyến cáo bảo mật GitHub (GHSA-9qr9-h5gf-34mp) và phát hành phiên bản cập nhật
- Người dùng cần nâng cấp lên phiên bản mới nhất để giảm thiểu lỗ hổng
- Trường hợp này một lần nữa nhấn mạnh tầm quan trọng của quản lý bảo mật ở cấp độ framework
Tổng quan về lỗ hổng RCE
- Một lỗ hổng cho phép thực thi mã từ xa đã được phát hiện trong môi trường Next.js và React
- Tồn tại rủi ro kẻ tấn công có thể thực thi mã JavaScript tùy ý ở phía máy chủ
- Lỗ hổng này xảy ra trong quá trình xử lý mã nội bộ của gói Next.js
- Chưa công bố giải thích chi tiết về hàm hay mô-đun dễ bị tấn công cụ thể
Ảnh hưởng và ứng phó
- Vercel đã chính thức công bố vấn đề thông qua khuyến cáo bảo mật GitHub (GHSA-9qr9-h5gf-34mp)
- Khuyến cáo này được đăng trong mục thông báo bảo mật của kho lưu trữ Next.js
- Các phiên bản bị ảnh hưởng chưa được nêu rõ, nhưng phiên bản cập nhật đã được phát hành
- Khuyến nghị người dùng nâng cấp lên phiên bản ổn định mới nhất
Khuyến cáo bảo mật và biện pháp xử lý
- Mọi dự án sử dụng gói Next.js cần kiểm tra phiên bản ngay lập tức
- Cần giữ phiên bản Next.js trong
package.json ở mức mới nhất
- Ngoài việc phát hành phiên bản đã vá, Vercel không đề cập đến biện pháp giảm thiểu bổ sung nào
- Chi tiết kỹ thuật cụ thể của lỗ hổng vẫn chưa được công khai, chỉ cung cấp lượng thông tin hạn chế vì lý do bảo mật
Tầm quan trọng
- Lỗ hổng lần này cho thấy rủi ro thực thi mã trong môi trường render phía máy chủ
- Các đơn vị vận hành dịch vụ dựa trên React và Next.js cần áp dụng cập nhật bảo mật thường xuyên
- Lỗ hổng bảo mật ở cấp độ framework có thể ảnh hưởng trực tiếp đến bảo mật của toàn bộ ứng dụng
1 bình luận
Ý kiến trên Hacker News
Lỗ hổng lần này là trường hợp kịch bản tồi tệ nhất từng được cảnh báo từ khi RSC/server actions được đưa vào nay đã trở thành hiện thực
Máy chủ đã giải tuần tự trực tiếp đầu vào không đáng tin cậy từ client, rồi tìm module và tên export để thực thi
Có thể chặn bằng bản vá
hasOwnProperty, nhưng vấn đề gốc rễ là React đã không nhận thức rõ rằng mình đang tạo ra một lớp RPCCác framework RPC truyền thống như gRPC hay SOAP phân định ranh giới rõ ràng bằng schema tường minh và định nghĩa service, còn React lại có cách làm nguy hiểm hơn khi phơi bày mọi API mà bundler có thể nhìn thấy
Các vấn đề bảo mật phát sinh từ kiểu thiết kế này rất có thể sẽ còn lặp lại trong tương lai
Dù có schema tường minh đi nữa, nếu ở bước cuối vẫn để đầu vào không đáng tin cậy tham chiếu tới bất kỳ đối tượng nào trong namespace của server thì cũng vô ích
Chỉ những hàm được đánh dấu bằng
"use server"mới được phơi bày, và nhóm React cũng nhận thức rằng họ đang thiết kế một hệ thống RPCLoại lỗi này hoàn toàn cũng có thể xảy ra trong các hệ thống RPC khác (tôi là người đóng góp cho React)
Nhưng tiếp tục duy trì một repo private cũ kỹ cũng không phải lựa chọn tốt
Next chỉ có một ưu điểm duy nhất là build tĩnh
Nếu hỗ trợ đó bị ngừng thì không còn lý do gì để dùng nữa
Theo khuyến cáo bảo mật của Facebook/Meta, React Server Components phiên bản 19.0.0~19.2.0 có lỗ hổng thực thi mã từ xa (RCE) trước xác thực
Thông báo trên blog chính thức của React cũng giải thích rằng do cấu trúc cho phép client gọi hàm phía server, kẻ tấn công có thể tạo yêu cầu HTTP độc hại để thực thi mã tùy ý trên server
hasOwnProperty, thì có lẽ cuộc tấn công đã tham chiếu tới các thuộc tính trong chuỗi nguyên mẫu như__proto__Commit sửa lỗi có vẻ là commit này
Có vẻ nó đã bị squash cùng nhiều thay đổi khác nên chi tiết bị che khuất
Trong mã có thể thấy mẫu giới hạn danh sách hàm được phơi bày theo kiểu whitelist ở 4 nơi
Vercel đã chặn các mẫu yêu cầu độc hại bằng bảo vệ ở cấp nền tảng
Xem thông báo
Cloudflare cũng đã phản ứng sớm bằng quy tắc WAF
Dù vậy vẫn rất khuyến nghị cập nhật ngay các dependency của Next, React và các meta framework khác
bài blog của Deno Deploy/Subhosting
Tôi đã thử tái hiện lỗ hổng dựa trên repo PoC
react-server-dom-webpackđã được vá thì RCE vẫn chạy, nên có vẻ cơ chế chưa hoàn toàn khớpSẽ tốt hơn nếu có demo trong một dự án Next.js thực tế
Đến mức có câu “không có Vercel thì không có RCE”, vụ việc lần này đã phơi bày mối tương quan giữa môi trường hosting và bảo mật
Điểm CVE 10.0 là con số gây sốc đối với một dự án được dùng rộng rãi như thế này
Thế nhưng số lượt tải hằng tuần vẫn vượt 310 nghìn
Khó hiểu vì sao nhóm React lại dành thời gian cho một tính năng rối rắm như thế này
Tôi cũng nghi ngờ nó thực sự hơn SSR ở điểm nào, hay cải thiện hiệu năng được bao nhiêu
Từ sau khi đưa Hook vào, trải nghiệm lập trình đã tệ hơn, nhưng thay vì cải thiện điều đó thì họ lại thêm một tầng phức tạp khác
Thà để ta có thể dùng luồng điều khiển vốn có của JS một cách tự nhiên trong logic component còn hơn
Tôi xem nó như một tầng BFF (Backend for Frontend) được component hóa
Mỗi mảnh UI được nối trực tiếp với logic backend tương ứng, nên có thể lấy dữ liệu mà không cần gọi
fetchNhờ vậy frontend và backend dễ tiến hóa cùng nhau hơn, đồng thời chỉ tải đúng phần dữ liệu cần thiết một cách tinh vi
Cuối cùng, logic server dành riêng cho UI có thể được hòa vào cấu trúc component một cách tự nhiên
Mô hình dựa trên compiler của Svelte hay React dễ làm việc hơn nhiều
Vue, Svelte, Angular v.v. đều cần compiler riêng và phần mở rộng file riêng
Trong khi đó React/JSX lại được ưu ái ngay từ bước tiền xử lý
Rust đã giải quyết kiểu vấn đề này bằng hệ thống macro — chẳng hạn Leptos hay Yew đều hỗ trợ JSX hoặc template HTML ngay trong file
.rschuẩnNếu JS không có được khả năng mở rộng như vậy, web rất có thể sẽ còn mắc kẹt trong một môi trường phức tạp và kém hiệu quả
Họ muốn giảm tải phía client, nhưng cảm giác ngay cả việc đó cũng không thành công
Giải thích chi tiết trên blog React cũng rất đáng đọc