CSRF Protection trong Laravel

CSRF Protection trong Laravel
Cross-site request forgeries 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 (CSRF) trên nhiều trang web.

Giải thích về lỗ hổng bảo mật

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ó /user/ đường dẫn email chấp nhận yêu cầu POST để thay đổi địa chỉ email của người dùng đã xác thực. Nhiều khả năng, route này yêu cầu một trường nhập email chứa địa chỉ email mà người dùng muốn bắt đầu sử dụng.

Nế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 đường dẫn /user/ email 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:

<form action="https://your-application.com/user/email" method="POST">
    <input type="email" value="[email protected]">
</form>

<script>
    document.forms[0].submit();
</script>

 

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 dụ người dùng không nghi ngờ ứng dụng của bạn 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 ta cần kiểm tra mọi yêu cầu POST, PUT, PATCH hoặc DELETE đến để tìm giá trị phiên bí mật mà ứng dụng độc hại không thể truy cập.

Ngăn chặn yêu cầu CSRF

Laravel tự động tạo CSRF token cho mỗi phiên người dùng đang hoạt động do ứng dụng quản lý. Token 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 các 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, ứng dụng độc hại không thể truy cập vào nó.

Hiểu nôm na là khi các bạn gửi request lên website thì Laravel sẽ tạo một chuỗi string ngẫu nhiên và lưu vào session của php. Và khi mình muốn gửi data lên thì phải truyền thêm cái token đó để kiểm tra xem trùng nhau ko. Nếu không thì nó sẽ không cho xử lý.

use Illuminate\Http\Request;

Route::get('/token', function (Request $request) {
    $token = $request->session()->token();

    $token = csrf_token();

    // ...
});

Bất kể khi nào bạn submit form thì bạn nên thêm CSRF token ở trong form của bạn để middleware bảo vệ CSRF có thể xác thực request của bạn. Để thuận tiện bạn có thể xài ở blade template để tạo một trường ẩn CSRF token.

<form method="POST" action="/profile">
    
</form>

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 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ọ, bạn sẽ cần phải loại trừ tuyến xử lý webhook của Stripe khỏi chế độ bảo vệ CSRF vì Stripe sẽ không biết mã thông báo CSRF nào sẽ gửi đến các tuyến 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 phần mềm trung gian webApp\Providers\RouteServiceProvider áp dụng cho tất cả các route trong danh sách routes/web.php. 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 $except của phần mềm trung gian VerifyCsrfToken:

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/*',
    ];
}

 

Nếu các bạn có thắc mắc gì vui lòng bình luận ở bên dưới.

Cảm ơn bạn đã đọc hết bài viết này. 

Hồ Hữu Hiền

Mình là developer nên đôi khi viết bài không hay lắm mong các bạn thông cảm. Nếu muốn biết thêm thông tin về mình thì vui lòng vào website này để biết. https://huuhienqt.dev/

Bình luận (0)