Belajar Cyber Security #10: CSRF & Clickjacking — Token, SameSite, dan frame-ancestors

Di episode #9 kita bahas XSS — penyerang menyuntikkan skrip ke halaman yang dipercaya browser korban. Kali ini, di episode #10, saya catat serangan yang lebih “social” tapi tetap teknis: CSRF dan Clickjacking. Yang bikin saya merinding saat memahaminya bukan triknya, tapi kenyataanan bahwa browser saya sendiri jadi “kuda Troya” tanpa saya sadari.

CSRF: browser yang terlalu sopan

CSRF (Cross-Site Request Forgery) menurut saya adalah contoh paling jujur dari istilah “serangan lewat kepercayaan”. Bayangkan begini: ketika kita login ke sebuah situs, server menyimpan sesi di cookie. Nah, keunikan cookie adalah sifatnya otomatis dikirim oleh browser ke server yang SAMA setiap kali ada request — tanpa peduli kita sedang membuka tab mana. Saya menyebutnya browser yang terlalu sopan: ia selalu menyerahkan kartu identitas setiap kali diminta, tanpa mengecek siapa yang meminta.

Skenario klasiknya: saya sedang login di bank.example, lalu tanpa sengaja membuka halaman penyerang. Di halaman itu ternyata ada elemen tersembunyi — bisa gambar kecil, atau form yang langsung auto-submit — yang memicu request POST ke bank.example/transfer dengan parameter “transfer ke rekening penyerang”. Karena browser otomatis menyertakan cookie sesi saya, server bank menganggap request itu MILIK saya dan memprosesnya. Saya tidak mengklik apa pun yang terlihat; saya hanya “mampir” ke halaman yang salah.

<!-- di halaman penyerang, tersembunyi -->
<form action="https://bank.example/transfer" method="POST" id="f">
  <input type="hidden" name="ke" value="rekening-penyerang">
  <input type="hidden" name="jumlah" value="1000000">
</form>
<script>document.getElementById('f').submit();</script>

Contoh di atas saya tulis bukan sebagai panduan menyerang, tapi supaya bentuk ancamannya jelas: inilah yang harus kita pertahankan di aplikasi yang saya bangun sendiri. Konteks hukumnya juga jelas — menguji CSRF di sistem tanpa izin tertulis sama saja melanggar UU ITE.

Tiga pertahanan yang saya pakai

  • Token CSRF. Server menyisipkan token acak di setiap form (dan di header untuk request API). Request yang datang tanpa token valid dianggap palsu. Prinsipnya sederhana: penyerang bisa memicu browser mengirim cookie, tapi TIDAK bisa membaca isi halaman kita — jadi ia tidak pernah tahu token-nya.
  • SameSite cookie. atribut Set-Cookie: ...; SameSite=Lax memerintahkan browser TIDAK mengirim cookie saat request datang dari lintas situs. Chrome sudah default Lax sejak 2020, dan ini menutup sebagian besar kasus CSRF tanpa satu baris kode pun. SameSite=Strict lebih galak lagi, tapi bisa memutus link eksternal menuju halaman login.
  • Re-check saat state berubah. Untuk aksi sensitif (transfer, ganti password), minta ulang password atau kode OTP. Walaupun token bocor, penyerang tetap mentok di lapisan kedua.

Clickjacking: lapisan yang menipu mata

Clickjacking berbeda tapi sering dituding saudara CSRF. Triknya bukan cookie, tapi <iframe>. Penyerang memasang situsnya sendiri, lalu menumpuk iframe transparan berisi halaman asli target di atas tombol yang terlihat menarik — misal tombol “Menang hadiah!”. Pengguna mengira menekan tombol hadiah, padahal yang diklik adalah tombol “Like” atau “Transfer” di halaman asli yang tertumpuk. Matanya melihat satu hal, jarinya menyentuh yang lain.

Menutup pintu klik

  • Header X-Frame-Options: DENY atau SAMEORIGIN melarang halaman kita dimuat di iframe dari situs lain.
  • frame-ancestors di Content Security Policy: pengganti modern yang lebih fleksibel — default-src 'self' menolak semua iframe lintas situs. Ini juga solusi clickjacking yang saya sebut di pembahasan CSP episode #9.
  • Tombol aksi butuh konfirmasi eksplisit, bukan sekadar satu klik — memberi pengguna waktu sadar bahwa ada sesuatu yang tidak sesuai.

Yang saya bawa pulang

CSRF mengajarkan saya satu hal yang saya pegang sampai sekarang: kepercayaan otomatis antar-request itu nyaman tapi berbahaya. Setiap kali menulis endpoint yang mengubah data, dua pertanyaan selalu saya tanyakan sendiri — “apakah request ini benar-benar berasal dari form saya?” dan “apakah cookie-nya benar-benar boleh dikirim dari konteks ini?”. Token CSRF menjawab pertanyaan pertama, SameSite menjawab pertanyaan kedua. Keduanya murah dipasang, mahal kalau lupa.

Sumber

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *

Situs ini menggunakan Akismet untuk mengurangi spam. Pelajari bagaimana data komentar Anda diproses