Peramban mengirimkan kuki Anda bersama permintaan apa pun ke domain Anda, siapa pun yang menyebabkan permintaan itu. Jadi sebuah halaman di situs lain bisa memuat formulir yang mengirim ke situs Anda, dan bila pengunjung Anda sedang masuk, permintaan itu tiba dalam keadaan terautentikasi — dan tampak sepenuhnya sah dalam log Anda.

Apa yang bisa dilakukannya

  • Mengubah alamat surel, lalu meminta penyetelan ulang kata sandi ke alamat yang baru.
  • Memesan sesuatu, memindahkan sesuatu, menghapus sesuatu.
  • Apa pun yang situs Anda lakukan dengan sebuah POST dan sebuah sesi.

Tokennya

Nilai acak yang disimpan di sesi dan diulang di formulir. Halaman di situs lain tidak bisa membaca sesi Anda, karena itu tidak bisa mengetahui nilainya.

// when rendering the form
$_SESSION["csrf"] = $_SESSION["csrf"] ?? bin2hex(random_bytes(32));
?>
<input type="hidden" name="csrf" value="<?= htmlspecialchars($_SESSION['csrf']) ?>">
// when handling it
if (!hash_equals($_SESSION["csrf"] ?? "", $_POST["csrf"] ?? "")) {
    http_response_code(400); exit;
}
Bandingkan dengan hash_equals, bukan dengan ==. Perbandingan biasa berhenti pada karakter pertama yang berbeda, dan lamanya waktu itu membocorkan seberapa banyak token yang sudah benar.

Dan atribut kukinya

session.cookie_samesite = Lax

SameSite=Lax menyuruh peramban untuk sama sekali tidak mengirim kuki pada POST lintas situs, sehingga kelas serangan ini berhenti sebelum kode Anda melihatnya. Ini lapisan kedua, bukan pengganti: ia hanya melindungi di tempat perambannya masih baru dan berkelakuan baik.

GET tidak boleh mengubah apa pun

Tautan yang menghapus sesuatu adalah CSRF yang tinggal menunggu waktu — lebih buruk lagi, perayap atau pratinjau tautan akan memicunya sendiri. Apa pun yang mengubah keadaan harus berupa POST dengan token.
Kerangka kerja mana pun sudah membawanya, tertanam dan menyala. Kalau Anda mematikannya pada satu titik masuk supaya sesuatu bisa berjalan, titik itulah yang harus Anda periksa.