CSRF: Ancaman Tersembunyi di Balik Sesi Login dan Cara Ampuh Mencegahnya
Cross-Site Request Forgery (CSRF) adalah celah keamanan web yang sering luput dari perhatian developer karena serangannya tidak terlihat di log server. Tidak ada payload aneh, tidak ada SQL injection, tetapi korban bisa kehilangan data atau dana hanya karena membuka satu halaman web yang tampak tidak berbahaya. Artikel ini membedah cara kerja CSRF, demonstrasi eksploitasinya, serta langkah mitigasi yang wajib diterapkan pada aplikasi modern.
Bagaimana CSRF Bekerja
CSRF memanfaatkan satu perilaku bawaan browser: mengirim cookie session secara otomatis ke domain tujuan pada setiap request, termasuk request yang dipicu dari domain lain. Jika aplikasi hanya mengandalkan cookie untuk autentikasi, server tidak bisa membedakan apakah request berasal dari form resmi aplikasi atau dari halaman palsu milik penyerang.
Alur serangan umumnya seperti ini: korban sudah login pada aplikasi target dan memiliki cookie aktif. Saat korban mengunjungi situs penyerang, situs tersebut diam-diam mengirim request ke aplikasi target menggunakan identitas korban. Server melihat cookie yang valid, sehingga request diproses seolah-olah korban yang melakukan tindakan tersebut.
Contoh Implementasi: Endpoint Rentan dan Halaman Penyerang
Berikut contoh endpoint Express.js yang rentan karena hanya mengandalkan sesi tanpa validasi tambahan:
app.post('/transfer', (req, res) => {
// Tidak ada validasi origin maupun CSRF token
transferDana(req.session.userId, req.body.to, req.body.amount);
res.json({ status: 'ok' });
});
Penyerang cukup menyiapkan halaman HTML berikut dan memancing korban membukanya. Form langsung disubmit otomatis tanpa interaksi apa pun:
<!-- Halaman milik penyerang -->
<form action="https://bank.com/transfer" method="POST" id="f">
<input name="to" value="attacker-account">
<input name="amount" value="5000000">
</form>
<script>document.getElementById('f').submit();</script>
Karena browser menyertakan cookie sesi milik korban, server mengeksekusi transfer dan menganggapnya sebagai permintaan sah.
Analisis Keamanan
Dampak CSRF sangat bergantung pada fitur yang diekspos. Pada aplikasi perbankan, risikonya bisa berupa transfer dana. Pada aplikasi internal, penyerang dapat mengubah email admin, menambahkan akun baru, atau mengekspor data sensitif. Yang membuat CSRF berbahaya adalah sifatnya yang state-changing: cukup satu request POST yang sukses untuk mengubah data.
Perlu dicatat, menonaktifkan CORS bukan solusi, karena form submission seperti contoh di atas tidak terhalang oleh kebijakan CORS. Begitu pula membatasi IP, sebab request tetap berasal dari browser korban yang berada di jaringan sah.
Cara Pencegahan yang Efektif
Mitigasi terbaik adalah kombinasi berlapis (defense in depth). Pertama, gunakan atribut cookie SameSite=Lax atau Strict agar browser tidak mengirim cookie pada request lintas situs. Kedua, terapkan synchronizer token pattern: server membuat token unik per sesi, menyisipkannya ke form, lalu memverifikasi setiap request yang mengubah state.
Implementasi middleware validasi token di Express.js:
app.use((req, res, next) => {
if (req.method === 'GET') return next();
const token = req.body._csrf || req.headers['x-csrf-token'];
const expected = req.session.csrfToken;
if (!expected || token !== expected) {
return res.status(403).json({ error: 'CSRF token tidak valid' });
}
next();
});
Untuk API berbasis JSON, tambahan double-submit cookie atau pengecekan header Origin dan Referer memperkuat validasi. Pastikan juga endpoint kritis seperti transfer dan ganti password menggunakan metode POST atau PUT, bukan GET, agar tidak bisa dieksploitasi lewat tag <img> maupun link.
Kesimpulan
CSRF memanfaatkan kepercayaan otomatis browser terhadap cookie sesi. Serangan ini tidak memerlukan celah teknis rumit, cukup satu halaman HTML jahat dan korban yang sedang login. Perlindungannya sendiri sebenarnya sederhana: gunakan atribut cookie SameSite, terapkan CSRF token pada semua request yang mengubah state, dan validasi header Origin sebagai lapisan tambahan. Jangan pernah menganggap autentikasi berbasis cookie saja sudah cukup. Dengan menerapkan pertahanan berlapis ini, aplikasi Anda akan jauh lebih tahan terhadap salah satu celah keamanan web yang paling klasik namun paling merugikan.