Giả mạo yêu cầu trên nhiều trang web là một loại khai thác độc hại theo đó các lệnh trái phép được thực hiện thay mặt cho người dùng được xác thực. Rất may, Laravel giúp dễ dàng bảo vệ ứng dụng của bạn khỏi các cuộc tấn công giả mạo yêu cầu chéo trang [CSRF]
Giải thích về lỗ hổng
Trong trường hợp bạn không quen với việc giả mạo yêu cầu trên nhiều trang web, hãy thảo luận về một ví dụ về cách lỗ hổng này có thể bị khai thác. Hãy tưởng tượng ứng dụng của bạn có một tuyến đường
use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
5 chấp nhận yêu cầu use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
6 để thay đổi địa chỉ email của người dùng được xác thực. Rất có thể, lộ trình này yêu cầu trường nhập liệu use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
7 chứa địa chỉ email mà người dùng muốn bắt đầu sử dụngNếu không có bảo vệ CSRF, một trang web độc hại có thể tạo một biểu mẫu HTML trỏ đến tuyến đường
use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
5 của ứng dụng của bạn và gửi địa chỉ email của chính người dùng độc hại
document.forms[0].submit[];
Nếu trang web độc hại tự động gửi biểu mẫu khi trang được tải, người dùng độc hại chỉ cần thu hút người dùng ứng dụng của bạn không nghi ngờ truy cập trang web của họ và địa chỉ email của họ sẽ được thay đổi trong ứng dụng của bạn
Để ngăn chặn lỗ hổng này, chúng tôi cần kiểm tra mọi yêu cầu
use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
6, use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
1, use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
2 hoặc use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
3 để tìm giá trị phiên bí mật mà ứng dụng độc hại không thể truy cậpNgăn chặn yêu cầu CSRF
Laravel tự động tạo "mã thông báo" CSRF cho mỗi phiên người dùng đang hoạt động do ứng dụng quản lý. Mã thông báo này được sử dụng để xác minh rằng người dùng được xác thực là người thực sự đưa ra yêu cầu đối với ứng dụng. Vì mã thông báo này được lưu trữ trong phiên của người dùng và thay đổi mỗi khi phiên được tạo lại nên ứng dụng độc hại không thể truy cập mã thông báo này
Mã thông báo CSRF của phiên hiện tại có thể được truy cập thông qua phiên của yêu cầu hoặc thông qua hàm trợ giúp
use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
4use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
Bất cứ khi nào bạn xác định biểu mẫu HTML "POST", "PUT", "PATCH" hoặc "DELETE" trong ứng dụng của mình, bạn nên bao gồm trường 15 CSRF ẩn trong biểu mẫu để phần mềm trung gian bảo vệ CSRF có thể xác thực yêu cầu. Để thuận tiện, bạn có thể sử dụng lệnh
use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
6 Blade để tạo trường nhập mã thông báo ẩn________số 8Phần mềm trung gian
use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
7, được bao gồm trong nhóm phần mềm trung gian use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
8 theo mặc định, sẽ tự động xác minh rằng mã thông báo trong đầu vào yêu cầu khớp với mã thông báo được lưu trữ trong phiên. Khi hai mã thông báo này khớp với nhau, chúng tôi biết rằng người dùng được xác thực là người bắt đầu yêu cầuMã thông báo CSRF & SPA
Nếu bạn đang xây dựng một SPA đang sử dụng Laravel làm phụ trợ API, bạn nên tham khảo tài liệu về Laravel Sanctum để biết thông tin về cách xác thực với API của bạn và bảo vệ chống lại các lỗ hổng CSRF
Loại trừ URI khỏi Bảo vệ CSRF
Đôi khi, bạn có thể muốn loại trừ một nhóm URI khỏi bảo vệ CSRF. Ví dụ: nếu bạn đang sử dụng Stripe để xử lý thanh toán và đang sử dụng hệ thống webhook của họ, thì bạn sẽ cần loại trừ tuyến đường xử lý webhook Stripe của mình khỏi cơ chế bảo vệ CSRF vì Stripe sẽ không biết mã thông báo CSRF nào sẽ gửi đến tuyến đường của bạn
Thông thường, bạn nên đặt các loại tuyến đường này bên ngoài nhóm phần mềm trung gian
use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
8 mà
0 áp dụng cho tất cả các tuyến đường trong tệp
1. Tuy nhiên, bạn cũng có thể loại trừ các tuyến đường bằng cách thêm URI của chúng vào thuộc tính
2 của phần mềm trung gian
3use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
6Lưu ý
Để thuận tiện, phần mềm trung gian CSRF tự động bị tắt đối với tất cả các tuyến khi chạy thử nghiệm.
X-CSRF-TOKEN
Ngoài việc kiểm tra mã thông báo CSRF dưới dạng tham số POST, phần mềm trung gian
use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
7 cũng sẽ kiểm tra tiêu đề yêu cầu
5. Ví dụ: bạn có thể lưu trữ mã thông báo trong thẻ HTML
6use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
0Sau đó, bạn có thể hướng dẫn một thư viện như jQuery tự động thêm mã thông báo vào tất cả các tiêu đề yêu cầu. Điều này cung cấp khả năng bảo vệ CSRF đơn giản, thuận tiện cho các ứng dụng dựa trên AJAX của bạn bằng công nghệ JavaScript kế thừa
use Illuminate\Http\Request;
Route::get['/token', function [Request $request] {
$token = $request->session[]->token[];
1X-XSRF-TOKEN
Laravel lưu trữ mã thông báo CSRF hiện tại trong cookie
7 được mã hóa đi kèm với mỗi phản hồi do khung tạo ra. Bạn có thể sử dụng giá trị cookie để đặt tiêu đề yêu cầu
8Cookie này chủ yếu được gửi để tạo sự thuận tiện cho nhà phát triển vì một số khung và thư viện JavaScript, như Angular và Axios, tự động đặt giá trị của nó vào tiêu đề
8 trên các yêu cầu cùng nguồn gốc