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 file routes/web.php
bởi method mapWebRoutes
trong app/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ỗi user 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(); $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 ở file App\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 file VerifyCsrfToken
middleware
<?php namespace App\Http\Middleware; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware; class VerifyCsrfToken extends Middleware
{ 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ề.