Lewati ke isi

Keamanan/Cyber Security

Apa Itu CSRF dan Kenapa Formulir Website Butuh Token

CSRF membuat browser pengguna yang sedang login mengirim permintaan palsu. Pahami cara kerjanya, peran token CSRF, SameSite, dan pertahanan lainnya.

Terbit 6 menit baca

Jawaban singkat

CSRF (Cross-Site Request Forgery) adalah serangan yang memanfaatkan browser korban yang sedang login untuk mengirim permintaan yang tidak ia kehendaki, misalnya mengganti email akun. Token CSRF yang unik dan diperiksa server membuat permintaan palsu dari situs lain ditolak.

Daftar isi
  1. Bagaimana serangan CSRF terjadi?
  2. Contoh alurnya
  3. Kenapa formulir publik juga perlu dipikirkan?
  4. Bagaimana token CSRF menghentikannya?
  5. Perbandingan cara melindungi formulir
  6. Kapan cukup memakai bawaan framework, kapan perlu tambahan?
  7. Kesalahan umum yang membuat token tidak berguna
  8. Pertanyaan yang sering diajukan

CSRF, singkatan dari Cross-Site Request Forgery, adalah serangan yang membuat browser pengguna yang sedang login mengirim permintaan ke sebuah website tanpa disadari pemiliknya. Server menerima permintaan itu lengkap dengan cookie login yang sah, sehingga mengira pengguna sendiri yang memintanya. Token CSRF di formulir adalah cara utama membedakan permintaan asli dari permintaan titipan situs lain.

Yang dipertaruhkan bila formulir tidak dilindungi bisa serius: email akun admin diganti, password diubah, alamat pengiriman pesanan dialihkan, atau pengaturan toko dimodifikasi. Semua itu bisa terjadi hanya karena admin membuka halaman lain sambil masih login di dashboard.

Bagaimana serangan CSRF terjadi?

Contoh alurnya

Misalkan sebuah toko online punya formulir di dashboard untuk mengganti email akun. Saat formulir dikirim, browser mengirim permintaan POST ke /akun/ganti-email beserta cookie sesi admin. Bila server hanya memeriksa cookie, inilah yang bisa terjadi:

  1. Admin login ke dashboard toko, lalu membuka tab lain.
  2. Di tab itu, admin membuka halaman yang disiapkan penyerang, misalnya lewat link di email atau iklan.
  3. Halaman tersebut berisi formulir tersembunyi yang otomatis mengirim permintaan POST ke /akun/ganti-email milik toko, dengan email penyerang.
  4. Browser ikut mengirim cookie sesi admin, karena permintaannya menuju domain toko.
  5. Server melihat cookie yang sah dan menjalankan perubahan. Penyerang lalu memakai fitur "lupa password" untuk mengambil alih akun.

Penyerang tidak pernah melihat cookie atau isi halaman toko. Ia hanya "menumpang" pada login korban. Itulah sebabnya OWASP menggolongkan CSRF sebagai serangan terhadap permintaan yang mengubah data, bukan pencurian data secara langsung.

Kenapa formulir publik juga perlu dipikirkan?

Formulir kontak tanpa login memang risikonya lebih kecil, karena tidak ada sesi yang bisa ditumpangi. Namun formulir yang berjalan untuk pengguna terdaftar, seperti ubah profil, checkout, hapus data, atau pengaturan, adalah sasaran utama. Begitu juga endpoint API yang memakai cookie untuk autentikasi.

Bagaimana token CSRF menghentikannya?

Token CSRF adalah nilai acak yang dibuat server, disisipkan di formulir sebagai input tersembunyi, dan diperiksa kembali saat formulir dikirim. Situs penyerang tidak bisa membaca halaman toko karena dibatasi aturan same-origin browser, sehingga tidak tahu nilai tokennya. Permintaan palsunya tidak membawa token yang benar dan ditolak server.

Contoh bentuknya di HTML:

<form method="post" action="/akun/ganti-email">
  <input type="hidden" name="csrf_token" value="nilai-acak-dari-server">
  <input type="email" name="email">
  <button type="submit">Simpan</button>
</form>

Hampir semua framework modern sudah menyediakan ini. Di Laravel, cukup menambahkan @csrf di formulir Blade dan middleware akan memeriksanya. Di Django, tag {% csrf_token %} dipasang di dalam formulir dan middleware CSRF aktif secara bawaan. Di WordPress, plugin dan tema memakai nonce, misalnya wp_nonce_field() saat membuat formulir dan check_admin_referer() atau wp_verify_nonce() saat memprosesnya. Dokumentasi WordPress sendiri mengingatkan bahwa nonce bukan pengganti pemeriksaan hak akses pengguna.

Perbandingan cara melindungi formulir

OWASP menyarankan memakai perlindungan bawaan framework lebih dulu, lalu melengkapinya dengan lapisan lain.

CaraCara kerja singkatKekuatanKeterbatasan
Synchronizer tokenToken acak per sesi atau per formulir disimpan di server dan dicocokkanPertahanan utama untuk aplikasi dengan sesiPerlu disisipkan di setiap formulir dan permintaan AJAX
Signed double-submit cookieToken di cookie dan di permintaan, ditandatangani dan terikat ke sesiCocok untuk aplikasi statelessVersi tanpa tanda tangan mudah diakali
Fetch Metadata (Sec-Fetch-Site)Server menolak permintaan pengubah data yang berasal dari situs lainMudah dipasang di browser modernPerlu cadangan pemeriksaan Origin atau Referer
Atribut cookie SameSiteBrowser tidak mengirim cookie pada permintaan lintas situs tertentuMengurangi banyak skenario CSRFOWASP menyebutnya lapisan tambahan, bukan pengganti token
Header kustom untuk APIPermintaan wajib membawa header khusus yang memicu preflight CORSCocok untuk endpoint AJAXAman hanya bila CORS dikonfigurasi ketat

Kapan cukup memakai bawaan framework, kapan perlu tambahan?

Untuk website biasa yang dibangun dengan Laravel, Django, atau WordPress dengan plugin tepercaya, perlindungan bawaan yang tidak dimatikan biasanya sudah memadai, asalkan semua formulir yang mengubah data memakai metode POST dan menyertakan token. Masalah paling sering justru terjadi saat developer menonaktifkan pemeriksaan CSRF untuk rute tertentu supaya formulir "tidak error", lalu lupa mengaktifkannya kembali.

Tambahan lapisan diperlukan bila aplikasi melayani API yang dipakai dari banyak domain, memakai subdomain yang dikelola pihak lain, atau menangani transaksi bernilai tinggi. Untuk aksi yang sangat sensitif seperti mengganti email, password, atau rekening penarikan dana, OWASP juga menyarankan meminta konfirmasi ulang seperti memasukkan password lagi.

Kesalahan umum yang membuat token tidak berguna

  • Mengubah data lewat GET. Link seperti /hapus-produk?id=10 bisa dipicu dari tag gambar di situs lain. OWASP tegas meminta agar GET tidak dipakai untuk operasi yang mengubah data, dan SameSite=Lax tetap mengirim cookie pada navigasi GET lintas situs.
  • Token ada, tapi tidak diperiksa. Formulir menyertakan token, tetapi kode pemrosesnya tidak memvalidasi.
  • Token sama untuk semua pengguna atau mudah ditebak.
  • Menaruh token di URL, sehingga ikut tercatat di log atau header Referer.
  • Mematikan pengecekan untuk webhook atau API tanpa mengganti dengan autentikasi lain, misalnya tanda tangan permintaan.

CSRF juga sering dibahas bersama pencurian sesi. Bila cookie login sendiri yang dicuri, token CSRF tidak menolong, dan pembahasannya ada di session hijacking. Gambaran keamanan website yang lebih luas ada di panduan keamanan website bisnis.

Pertanyaan yang sering diajukan

Apakah HTTPS mencegah CSRF?

Tidak. HTTPS melindungi data saat dikirim, tetapi permintaan CSRF tetap dikirim browser korban lewat HTTPS dengan cookie yang sah.

Apakah CAPTCHA bisa menggantikan token CSRF?

Tidak disarankan. OWASP tidak merekomendasikan CAPTCHA sebagai pertahanan CSRF. Pakai token dari framework, dan untuk aksi sensitif minta konfirmasi password.

Website saya memakai WordPress, apakah perlu menambah sesuatu?

Inti WordPress sudah memakai nonce. Yang perlu dijaga adalah plugin dan tema: pasang dari sumber resmi, perbarui rutin, dan pastikan kode buatan sendiri memakai fungsi nonce serta memeriksa hak akses.

Apakah atribut SameSite saja sudah cukup?

Untuk sebagian besar aplikasi belum. OWASP menyebut SameSite sebagai lapisan pertahanan tambahan yang tidak menggantikan token CSRF kecuali pada kondisi yang sangat terbatas.

Sumber & referensi

Baca juga