Kiến trúc bảo mật Next.js 15: Tăng cường Server Actions chống lại CSRF, SSRF & State Injection

Mục lục bài viết(3 mục)
Next.js 15 mang đến những thay đổi kiến trúc đáng kể, đặc biệt là với React 19 và các khả năng nâng cao của Server Actions. Mặc dù các tính năng này giúp hợp lý hóa quá trình phát triển full-stack, nhưng chúng cũng mở rộng bề mặt tấn công của ứng dụng. Hướng dẫn này trình bày chi tiết kiến trúc bảo mật mạnh mẽ để củng cố Server Actions của Next.js 15 chống lại các lỗ hổng web phổ biến, bao gồm Cross-Site Request Forgery (CSRF), Server-Side Request Forgery (SSRF) và state injection. Trọng tâm là triển khai các chiến lược phòng thủ chuyên sâu bằng cách sử dụng các mẫu cấp độ sản xuất.
Hiểu về bề mặt tấn công của Next.js 15 Server Actions
Server Actions trong Next.js 15 là các hàm bất đồng bộ thực thi trực tiếp trên máy chủ. Chúng có thể được gọi từ các client component, server component hoặc trực tiếp từ các biểu mẫu HTML. Mô hình này đơn giản hóa việc thay đổi dữ liệu và logic phía máy chủ, biến việc gửi biểu mẫu và các lệnh gọi hàm phía máy khách thành các lệnh gọi API trực tiếp phía máy chủ.
Các vấn đề bảo mật chính phát sinh từ:
- Thực thi trực tiếp trên máy chủ: Server Actions chạy trong một môi trường đặc quyền, thường có quyền truy cập vào cơ sở dữ liệu, dịch vụ nội bộ và các biến môi trường nhạy cảm.
- Gọi từ phía máy khách: Mặc dù Server Actions thực thi trên máy chủ, nhưng việc gọi chúng được kích hoạt bởi các sự kiện phía máy khách (gửi biểu mẫu, lệnh gọi
startTransition). Điều này khiến chúng dễ bị tấn công bởi các vector tấn công web điển hình bắt nguồn từ máy khách. - Không trạng thái theo thiết kế: Server Actions thường không trạng thái, xử lý một yêu cầu duy nhất. Tuy nhiên, trạng thái có thể được quản lý ngầm thông qua cookie hoặc được truyền rõ ràng qua dữ liệu biểu mẫu, khiến việc state injection trở thành một mối lo ngại.
- Các endpoint POST ngầm: Mỗi Server Action thực sự tạo ra một endpoint POST. Nếu không có sự bảo vệ rõ ràng, các endpoint này dễ bị tấn công bởi các lệnh gọi không được xác thực hoặc độc hại.
Bảo mật Server Actions yêu cầu một cách tiếp cận đa lớp, kết hợp các kiểm soát cấp độ mạng, xác thực đầu vào mạnh mẽ và các tiêu đề bảo mật cấp độ ứng dụng.
Bảo vệ chống lại Cross-Site Request Forgery (CSRF)
Các cuộc tấn công CSRF khai thác sự tin cậy của một ứng dụng web vào trình duyệt của người dùng đã được xác thực. Một trang web độc hại có thể lừa trình duyệt của người dùng gửi một yêu cầu đã được xác thực đến ứng dụng của bạn, thực hiện các hành động mà không có sự đồng ý rõ ràng của người dùng.
Bảo vệ tích hợp của Next.js 15 & Xác minh Host/Origin
Server Actions của Next.js 15, khi được gọi qua fetch từ trình duyệt, vốn dĩ được hưởng lợi từ các cơ chế bảo mật cấp độ trình duyệt. Cụ thể, các tiêu đề Origin và Host rất quan trọng.
- Tiêu đề
Origin: Được gửi cùng với các yêu cầu cross-origin (bao gồm cả việc gửi biểu mẫu đến một origin khác). Nó cho biết origin của yêu cầu. - Tiêu đề
Host: Cho biết tên miền của máy chủ mà yêu cầu đang được gửi đến.
Đối với Server Actions, Next.js nội bộ sử dụng các tiêu đề này để xác thực. Tuy nhiên, xác thực rõ ràng trong một middleware.ts cung cấp một lớp phòng thủ bổ sung và cho phép xử lý lỗi tùy chỉnh.
Giải thích kiến trúc:
Một tệp middleware.ts chạy trước khi một yêu cầu được xử lý bởi một trình xử lý tuyến đường hoặc Server Action. Đây là nơi lý tưởng để thực hiện các kiểm tra bảo mật toàn cầu như xác thực Host/Origin. Bằng cách so sánh tiêu đề Origin (nếu có) và tiêu đề Host với miền ứng dụng dự kiến của bạn, bạn có thể từ chối các yêu cầu bắt nguồn từ các nguồn không đáng tin cậy.
// middleware.ts
import { NextResponse, type NextRequest } from 'next/server';
const ALLOWED_HOSTS = process.env.NEXT_PUBLIC_ALLOWED_HOSTS
? process.env.NEXT_PUBLIC_ALLOWED_HOSTS.split(',')
: ['locionic.com', 'www.locionic.com']; // Replace with your actual domains
export async function middleware(request: NextRequest) {
const host = request.headers.get('host');
const origin = request.headers.get('origin');
const xInvokeAction = request.headers.get('x-invoke-action'); // Specific to Server Actions
// 1. Host Header Validation
if (host && !ALLOWED_HOSTS.includes(host)) {
console.warn(`CSRF: Blocked request due to untrusted Host: ${host}`);
return new NextResponse('Unauthorized Host', { status: 403 });
}
// 2. Origin Header Validation for Server Actions
// Server Actions typically send an 'Origin' header, especially cross-origin.
// For same-origin requests, 'Origin' might be null or same as 'Host'.
// We specifically check 'x-invoke-action' to target Server Action requests.
if (xInvokeAction) {
if (origin && !ALLOWED_HOSTS.some(allowedHost => origin.endsWith(allowedHost))) {
console.warn(`CSRF: Blocked Server Action due to untrusted Origin: ${origin}`);
return new NextResponse('Unauthorized Origin for Server Action', { status: 403 });
}
// If origin is null/undefined for a Server Action, it's likely a same-origin form submission
// or a non-browser client. Further checks might be needed for non-browser clients.
}
return NextResponse.next();
}
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
* - api/auth (auth routes, if handled separately)
* - Any public files in /public folder
*/
'/((?!_next/static|_next/image|favicon.ico|api/auth|.*\\.(?:png|jpg|jpeg|gif|webp|svg|ico|js|css|map)$).*)',
],
};
Đánh đổi & Độ trễ:
| Phương pháp | Mức độ bảo vệ | Độ phức tạp | Tác động độ trễ | Đánh đổi
Free In-Browser Developer Tools
Clean AI CLI logs, build cron expressions, decode JWTs, and calculate chmod permissions offline.
Related Articles

Next.js 15 Server Actions vs Route Handlers: So sánh kiến trúc chuyên sâu
Nắm vững khi nào nên chọn Server Actions so với Route Handlers trong Next.js 15, đi sâu vào progressive enhancement, hành vi caching, giao thức RPC và các ranh giới bảo mật.
Read more
Xử lý Form trong Next.js 14: Server Actions và Client Components
Tìm hiểu sâu về cách quản lý form trong Next.js 14 bằng Server Actions, useFormState, useFormStatus và Zod để xác thực schema, giúp bạn xây dựng các form hiện đại, nâng cao dần mà không mệt mỏi với JavaScript phía client.
Read more
tRPC v11 với Next.js 15: An toàn kiểu dữ liệu từ đầu đến cuối, Server Actions & TanStack Query v5
Hướng dẫn toàn diện về tRPC v11 với Next.js 15: an toàn kiểu dữ liệu từ đầu đến cuối, Server Actions & TanStack Query v5 với kiến trúc cấp độ sản phẩm và các ví dụ code.
Read more