Laravel CSRF Protection
Introduction
- CSRF (Cross-site request forgeries) là một dạng giả mạo tấn công ứng dụng thông qua request
- Laravel xây dựng sẵn cơ chế để chống tấn công giả mạo CSRF
- Laravel mặc định sẽ bảo vệ CSRF với các method POST, PUT, PATCH, or DELETE của route web
- CSRF được verify trong VerifyCsrfToken middleware, khai báo trong mảng thuộc tính $middlewareGroups cho các route
web
và được tự động sử dụng cho các route trong fileroutes/web.php
bởi methodmapWebRoutes
trongapp/Providers/RouteServiceProvider.php
)
An Explanation Of The Vulnerability
- Kẻ tấn công ứng dụng có thể gửi 1 form request đến url của bạn để thực hiện các hành động độc hại
<form action="https://your-application.com/user/email" method="POST">
<input type="email" value="malicious-email@example.com">
</form>
<script>
document.forms[0].submit();
</script>
- Nếu không có bảo vệ CSRF thì không thể phân biệt đâu là request giả mạo đâu là request từ ứng dụng của bạn
Preventing CSRF Requests
- Để chống tấn công giả mạo CSRF, laravel tự động sinh ra 1 CSRF
token
cho mỗiuser session
. Token này để xác thực người dùng của ứng dụng, khi kết thúc 1 session người dùng thìtoken
này sẽ bị xóa và tạo lại vào phiên làm việc tiếp theo. - Mã
token
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 chức năng trợ giúp csrf_token:
use Illuminate\Http\Request;
Route::get('/token', function (Request $request) {
$token = $request->session()->token();
//OR
$token = csrf_token();
// ...
});
- Sau đó với mỗi method "POST", "PUT", "PATCH", or "DELETE" của HTMLD form trong ứng dụng. bạn cần thêm 1 trường ẩn CSRF
token
vào trong biểu form HTML, sau đótoken
từ request sẽ được verify với token lưu trong sesion ở fileApp\Http\Middleware\VerifyCsrfToken
<form method="POST" action="/profile">
@csrf
<!-- Equivalent to... -->
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
</form>
Excluding URIs From CSRF Protection
- Đôi khi bạn muốn loại bỏ route khỏi bảo vệ CSRF, thông thường bạn có thể khai báo route ngoài nhóm route web trong file
routes/web.php
, tuy nhiên bạn có thể loại bỏ route khỏi bảo vệ CSRF bằng cách thêm url vào mảng thuộc tính$except
trong fileVerifyCsrfToken
middleware
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
'stripe/*',
'http://example.com/foo/bar',
'http://example.com/foo/*',
];
}
X-CSRF-TOKEN
- Ngoài việc kiểm tra mã thông báo CSRF dưới dạng tham số POST, middleware App\Http\Middleware\VerifyCsrfToken cũng sẽ kiểm tra X-CSRF-TOKEN thông qua request header. Ví dụ: bạn có thể lưu trữ
token
trong thẻ meta HTML:
<meta name="csrf-token" content="{{ csrf_token() }}">
- Khi đó bạn có thể thêm
token
bằng jquery cho các request header
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
X-XSRF-TOKEN
- Laravel lưu CSRF token hiện tại trong cookie XSRF-TOKEN được mã hóa đi kèm mỗi response trả về.
All rights reserved