Laravel: Bảo vệ CSRF
Mục lục bài viết:
Giới thiệu
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 trên nhiều trang web (Cross-Site Request Forgery - CSRF). Giả mạo yêu cầu trên nhiều trang web là một kiểu 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.
Laravel tự động tạo "mã thông báo - token" 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 đã xác thực là người thực sự đưa ra yêu cầu đối với ứng dụng.
Bất cứ khi nào bạn tạo một form HTML trong ứng dụng của mình, bạn cần đưa vào trường mã token CSRF ẩn trong form để middleware bảo vệ CSRF có thể xác thực yêu cầu. Bạn có thể sử dụng chỉ thị Blade @csrf
để tạo trường mã thông báo:
<form method="POST" action="/profile">
@csrf
...
</form>
Middleware VerifyCsrfToken
được đưa vào trong nhóm middleware web
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.
Token CSRF và JavaScript
Khi xây dựng các ứng dụng dựa trên JavaScript, thật tiện lợi khi thư viện JavaScript HTTP của bạn tự động đính kèm mã token CSRF cho mọi yêu cầu gửi đi. Theo mặc định, thư viện Axios HTTP được cung cấp trong file resources/js/bootstrap.js sẽ tự động gửi header X-XSRF-TOKEN bằng cách sử dụng giá trị của cookie XSRF-TOKEN được mã hóa. Nếu bạn không sử dụng thư viện này, bạn sẽ cần phải định cấu hình thủ công hành vi này cho ứng dụng của mình.
Loại trừ URI khỏi Bảo vệ CSRF
Đôi khi bạn có thể muốn loại trừ một tập hợp các URI khỏi token 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ọ, bạn sẽ cần phải loại trừ tuyến xử lý webhook của Stripe khỏi tính năng bảo vệ CSRF vì Stripe sẽ không biết mã thông báo CSRF nào cần gửi đến các route của bạn.
Thông thường, bạn nên đặt các loại route này bên ngoài nhóm middleware web
mà RouteServiceProvider
áp dụng cho tất cả các route trong file routes/web.php. Tuy nhiên, bạn cũng có thể loại trừ các route bằng cách thêm URI của chúng vào thuộc tính $except của middleware VerifyCsrfToken:
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* Các URI cần được loại trừ khỏi xác minh CSRF.
*
* @var array
*/
protected $except = [
'stripe/*',
'http://example.com/foo/bar',
'http://example.com/foo/*',
];
}
Middleware CSRF sẽ tự động bị vô hiệu hóa khi chạy thử nghiệm.
X-CSRF-TOKEN
Ngoài việc kiểm tra token CSRF dưới dạng tham số POST, middleware VerifyCsrfToken
cũng sẽ kiểm tra header request X-CSRF-TOKEN. Ví dụ: bạn có thể lưu trữ mã thông báo trong thẻ <meta>:
<meta name="csrf-token" content="{{ csrf_token() }}">
Sau đó, khi bạn đã tạo thẻ meta, 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 header request. Điều này cung cấp token CSRF đơn giản, thuận tiện cho các ứng dụng dựa trên AJAX của bạn:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
X-XSRF-TOKEN
Laravel lưu trữ token CSRF hiện tại trong một cookie XSRF-TOKEN được mã hóa đi kèm với mỗi phản hồi được tạo bởi framework. Bạn có thể sử dụng giá trị cookie để đặt header request X-XSRF-TOKEN.
Cookie này chủ yếu được gửi nhằm mục đích thuận tiện vì một số framework JavaScript và thư viện như Angular và Axios, tự động đặt giá trị của nó trong header X-XSRF-TOKEN trên các yêu cầu có cùng nguồn gốc.
Theo mặc định, file resources/js/bootstrap.js bao gồm thư viện Axios HTTP sẽ tự động gửi tệp này cho bạn.