Skip to content

Latest commit

 

History

History
127 lines (87 loc) · 7.09 KB

csrf.md

File metadata and controls

127 lines (87 loc) · 7.09 KB

CSRF Protection

Pendahuluan

Cross-site request forgeries adalah jenis eksploitasi berbahaya di mana perintah yang tidak sah dilakukan atas nama pengguna yang terautentikasi. Untungnya, Laravel telah memudahkan perlindungan aplikasi Anda dari serangan cross-site request forgery (CSRF).

Penjelasan Kerentanan

Jika Anda belum akrab dengan istilah cross-site request forgery (CSRF), mari kita bahas contoh bagaimana kerentanan ini dapat dieksploitasi. Bayangkan apabila aplikasi Anda memiliki route /pengguna/email yang menerima request POST untuk mengubah alamat email pengguna yang terotentikasi. Kemungkinan besar, route ini mengharapkan kolom input email yang berisi alamat email yang ingin didaftarkan oleh pengguna.

Tanpa perlindungan CSRF, situs web berbahaya dapat membuat formulir HTML yang mengarah ke route /user/email aplikasi Anda dan mengirimkan alamat email "jahat" milik peretas:

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

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

Jika situs web berbahaya dapat mengirimkan formulir secara otomatis ketika halaman dimuat, pengguna jahat hanya perlu memperdaya pengguna (asli) aplikasi Anda yang tidak menaruh curiga untuk mengunjungi situs web mereka, kemudian alamat email mereka pada aplikasi Anda akan tertimpa oleh alamat email "jahat" milik peretas.

Untuk mencegah kerentanan ini, kita perlu memeriksa nilai rahasia sesi pada setiap request POST, PUT, PATCH, atau DELETE yang masuk. Nilai rahasia yang tidak dapat diakses oleh aplikasi jahat.

Mencegah request CSRF

Laravel secara otomatis menghasilkan "token" CSRF untuk setiap sesi pengguna yang aktif yang dikelola oleh aplikasi secara otomatis. Token ini digunakan untuk memverifikasi bahwa pengguna yang telah terautentikasi adalah orang yang benar-benar membuat request ke aplikasi. Karena token ini disimpan dalam sesi pengguna dan berubah setiap kali sesi diregenerasi (dihasilkan ulang), aplikasi jahat tidak akan dapat mengaksesnya.

Token CSRF untuk sesi saat ini dapat diakses melalui request milik sesi atau melalui fungsi helper csrf_token:

use Illuminate\Http\Request;

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

    $token = csrf_token();

    // ...
});

Setiap kali Anda mendefinisikan formulir HTML "POST", "PUT", "PATCH", atau "DELETE" dalam aplikasi Anda, Anda harus menyertakan kolom _token CSRF yang tersembunyi pada formulir tersebut sehingga middleware untuk perlindungan CSRF dapat memvalidasi request untuk formulir tersebut. Untuk kemudahan, Anda dapat menggunakan directive @csrf milik Blade untuk menghasilkan kolom input token yang tersembunyi:

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

    <!-- Setara dengan... -->
    <input type="hidden" name="_token" value="{{ csrf_token() }}" />
</form>

Middleware App\Http\Middleware\VerifyCsrfToken yang telah termasuk di dalam grup middleware web secara default, akan secara otomatis memverifikasi bahwa token di dalam input pada request telah sesuai dengan token yang tersimpan di dalam sesi. Ketika kedua token ini cocok, maka kita mengetahui bahwa pengguna yang terotentikasi adalah yang pengguna yang melakukan request.

Token CSRF & SPA

Jika Anda membangun sebuah SPA yang menggunakan Laravel sebagai backend API, Anda sebaiknya mengunjungi dokumentasi Laravel Sanctum untuk informasi tentang autentikasi dengan API dan perlindungan terhadap kerentanan CSRF pada aplikasi Anda.

Pengecualian URI dari Perlindungan CSRF

Terkadang Anda mungkin ingin mengecualikan sekumpulan URI dari perlindungan CSRF. Misalnya, jika Anda menggunakan Stripe untuk memproses pembayaran dan menggunakan sistem webhook mereka, Anda perlu mengecualikan rute handler untuk webhook milik Stripe dari perlindungan CSRF karena Stripe tidak pernah tahu token CSRF apa yang perlu dikirim ke rute Anda.

Biasanya, Anda harus menempatkan rute-rute semacam ini di luar grup middleware web yang diterapkan oleh App\Providers\RouteServiceProvider ke semua rute yang terdapat di dalam file routes/web.php. Atau, Anda juga dapat mengecualikan rute-rute tersebut dengan menambahkan URI tersebut ke properti $except pada middleware VerifyCsrfToken:

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
    /**
     * URI yang seharusnya dikecualikan dari verifikasi CSRF.
     *
     * @var array
     */
    protected $except = [
        'stripe/*',
        'http://example.com/foo/bar',
        'http://example.com/foo/*',
    ];
}

Catatan
Untuk kenyamanan, middleware CSRF secara otomatis dinonaktifkan pada semua rute ketika melakukan pengujian.

X-CSRF-TOKEN

Selain memeriksa token CSRF sebagai parameter POST, middleware App\Http\Middleware\VerifyCsrfToken juga akan memeriksa header X-CSRF-TOKEN pada request. Misalnya, Anda dapat menyimpan token di dalam tag meta HTML:

<meta name="csrf-token" content="{{ csrf_token() }}">

Kemudian, Anda dapat menginstruksikan library seperti jQuery untuk menambahkan token secara otomatis ke semua header untuk request. Hal ini bertujuan untuk memberikan perlindungan CSRF yang sederhana dan nyaman untuk aplikasi berbasis AJAX yang menggunakan teknologi JavaScript lama

$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});

X-XSRF-TOKEN

Laravel menyimpan token CSRF saat ini yang telah terenkripsi di dalam cookie XSRF-TOKEN yang disertakan pada setiap respons yang dihasilkan oleh framework. Anda dapat menggunakan nilai cookie ini untuk menetapkan nilai X-XSRF-TOKEN pada header request.

Pada dasarnya cookie ini dikirim untuk kenyamanan pengembang karena beberapa framework dan library JavaScript, seperti Angular dan Axios, secara otomatis menempatkan nilai tersebut di header X-XSRF-TOKEN untuk asal request yang sama (same-origin request).

Catatan
Secara default, file resources/js/bootstrap.js menyertakan pustaka HTTP Axios yang secara otomatis akan mengirimkan header X-XSRF-TOKEN untuk Anda.