Session fixation adalah serangan ketika aplikasi tetap memakai session ID yang sama sebelum dan sesudah login. Jika penyerang sudah mengetahui ID tersebut lebih dulu, ia bisa menunggu korban login lalu memakai session yang sama untuk masuk sebagai korban.
Mitigasi utamanya sederhana tetapi sering terlewat: regenerasi session ID setelah login, logout, dan perubahan privilege, lalu invalidasi session lama. Di aplikasi web modern, langkah itu perlu dilengkapi dengan pengaturan cookie yang benar, masa berlaku session yang masuk akal, binding secukupnya ke konteks request, serta logging untuk mendeteksi pola anomali.
Apa itu session fixation?
Pada banyak aplikasi web, server mengaitkan status login dengan sebuah session identifier yang dikirim lewat cookie, misalnya session_id. Dalam kondisi aman, ID session yang dipakai setelah autentikasi seharusnya tidak bisa diprediksi dan tidak boleh diwariskan dari sesi anonim tanpa rotasi.
Pada session fixation, masalah utamanya bukan penyerang mencuri session yang aktif, melainkan menetapkan session ID lebih dulu agar nanti dipakai oleh korban. Karena itu, session fixation berbeda dari session hijacking klasik yang biasanya bergantung pada pencurian cookie aktif lewat XSS, malware, atau jaringan yang tidak aman.
Bagaimana serangan terjadi
Skenario sebelum login
Alur yang paling umum adalah:
- Penyerang mendapatkan atau membuat session anonim dari aplikasi.
- Session ID tersebut dikirim ke korban, misalnya lewat tautan, subdomain yang salah konfigurasi, injeksi header, atau mekanisme aplikasi yang menerima session ID dari URL atau parameter request.
- Korban membuka aplikasi dan browser menyimpan session ID itu.
- Korban login.
- Jika aplikasi tidak merotasi session ID setelah login, maka session yang tadinya anonim berubah menjadi session terautentikasi dengan ID yang tetap sama.
- Penyerang memakai ID yang sudah diketahui tadi untuk mengakses akun korban.
Poin kuncinya: aplikasi tidak boleh menganggap session anonim aman untuk dipromosikan langsung menjadi session login tanpa rotasi.
Skenario sesudah login
Session fixation juga bisa relevan setelah login, terutama saat ada perubahan tingkat hak akses. Contohnya:
- pengguna biasa naik menjadi admin setelah verifikasi tambahan,
- pengguna melewati langkah autentikasi kedua,
- session dipakai kembali setelah proses reauthentication,
- perpindahan dari area publik ke area sensitif seperti billing atau manajemen akses.
Jika session ID tidak diganti saat privilege berubah, ID yang sama tetap berlaku untuk konteks yang sekarang lebih sensitif. Ini memperbesar dampak bila ID tersebut sebelumnya sudah terekspos atau diset oleh pihak lain.
Kapan aplikasi rentan?
Aplikasi biasanya lebih rentan terhadap session fixation bila memiliki satu atau lebih kondisi berikut:
- Tidak merotasi session ID setelah login. Ini adalah penyebab paling umum.
- Menerima session ID dari URL, query parameter, atau form field. Praktik ini sebaiknya dihindari.
- Domain atau subdomain tidak tertata baik. Cookie yang terlalu luas cakupannya dapat diset dari konteks lain yang tidak seharusnya.
- Ada reverse proxy atau middleware yang salah mengelola header. Misalnya aplikasi percaya pada request yang bisa memengaruhi setelan cookie atau skema koneksi secara keliru.
- Transisi anonim ke login memakai state session yang sama. Misalnya keranjang belanja, CSRF token, atau wizard form dipertahankan tanpa rotasi identifier.
- Logout tidak benar-benar menghapus session server-side. Akibatnya ID lama masih hidup.
- Aplikasi terlalu mengandalkan cookie tanpa atribut keamanan yang tepat.
Aplikasi modern berbasis SPA, SSR, atau API gateway tetap bisa terkena masalah ini bila backend session management tidak benar. Teknologi frontend tidak menghilangkan risiko jika identitas session tetap dipertahankan secara salah di server.
Dampak session fixation
- Pengambilalihan akun tanpa perlu mengetahui password korban.
- Eskalasi akses bila fixation terjadi sebelum perubahan privilege.
- Pelanggaran audit trail karena dua pihak tampak menggunakan session yang sama.
- Kompromi data sensitif seperti profil, alamat, data bisnis, atau konfigurasi akun.
Jika aplikasi hanya memiliki satu lapisan proteksi berupa cookie session, maka session fixation bisa memberikan hasil yang setara dengan login penuh sebagai korban.
Mitigasi utama: rotasi session ID pada titik yang tepat
1. Regenerasi session ID setelah login
Setelah kredensial tervalidasi, jangan lanjut memakai session anonim yang sama. Buat session ID baru, pindahkan state yang memang aman untuk dipertahankan, lalu hapus atau invalidasi session lama.
Ini efektif karena penyerang hanya mengetahui session ID lama. Ketika korban berhasil login, identifier berubah sehingga ID yang sudah diketahui tidak lagi mewakili sesi autentikasi korban.
2. Regenerasi lagi saat privilege berubah
Rotasi session sebaiknya tidak hanya dilakukan saat login awal, tetapi juga ketika konteks keamanan berubah, misalnya:
- setelah MFA berhasil,
- setelah re-auth untuk aksi sensitif,
- setelah role berubah,
- setelah pengguna berpindah ke area admin.
Prinsipnya: setiap kali nilai session meningkat dari sisi risiko, pertimbangkan rotasi identifier.
3. Regenerasi atau ganti session saat logout dan login ulang
Saat logout, hapus session server-side dan minta browser menghapus cookie. Jika pengguna login lagi, buat session baru, bukan mengaktifkan kembali yang lama.
4. Invalidasi session lama, bukan hanya membuat ID baru
Kesalahan umum adalah membuat ID baru tetapi membiarkan session lama tetap valid untuk beberapa waktu. Ini membuka jendela serangan. Setelah rotasi, pastikan session lama tidak bisa dipakai lagi.
Catatan: Beberapa framework menyediakan API seperti regenerate, renew, atau migrate. Pastikan Anda memahami apakah API tersebut juga menghapus session lama atau hanya mengganti ID. Nama metodenya bisa mirip, tetapi perilakunya tidak selalu sama.
Alur implementasi umum di backend web
Berikut alur generik yang dapat diterapkan pada backend berbasis session server-side:
// Request login masuk dengan session anonim yang mungkin sudah ada
POST /login
1. Validasi kredensial pengguna.
2. Jika gagal, jangan ubah session menjadi terautentikasi.
3. Jika berhasil:
a. Buat session ID baru yang acak dan kuat.
b. Salin hanya state yang diperlukan dari session lama
(misalnya preferensi non-sensitif atau CSRF state yang relevan).
c. Tandai user_id, auth_time, dan privilege pada session baru.
d. Invalidasi session lama di penyimpanan server.
e. Kirim Set-Cookie baru dengan atribut keamanan yang benar.
4. Catat event login dan rotasi session.
5. Lanjutkan request dengan session baru.Jika aplikasi Anda menyimpan session di Redis, database, atau memory store terdistribusi, pastikan invalidasi session lama bersifat konsisten di semua node. Dalam arsitektur multi-instance, bug yang sering muncul adalah session lama masih terbaca di node lain karena sinkronisasi, TTL, atau cache yang tidak tepat.
Contoh pseudocode
function handleLogin(request, response) {
const user = verifyCredentials(request.body.email, request.body.password)
if (!user) {
return response.status(401).send("Login gagal")
}
const oldSessionId = request.session.id
const preservedState = {
locale: request.session.locale,
csrfSeed: request.session.csrfSeed
}
const newSession = createEmptySession()
newSession.userId = user.id
newSession.authenticatedAt = now()
newSession.role = user.role
newSession.locale = preservedState.locale
newSession.csrfSeed = preservedState.csrfSeed
saveSession(newSession)
invalidateSession(oldSessionId)
response.setCookie("session_id", newSession.id, {
secure: true,
httpOnly: true,
sameSite: "Lax",
path: "/"
})
logSecurityEvent("session_rotated_after_login", {
userId: user.id,
oldSessionIdHash: hashForLog(oldSessionId),
newSessionIdHash: hashForLog(newSession.id)
})
return response.redirect("/dashboard")
}Pseudocode di atas sengaja generik. Di implementasi nyata, jangan pernah menulis session ID mentah ke log. Simpan nilai yang sudah di-hash atau token internal untuk korelasi.
Hardening cookie: Secure, HttpOnly, SameSite
Secure
Setel cookie session dengan atribut Secure agar hanya dikirim melalui HTTPS. Ini tidak menyelesaikan session fixation sendirian, tetapi mengurangi risiko kebocoran cookie di jalur yang tidak terenkripsi.
HttpOnly
HttpOnly mencegah JavaScript di browser membaca cookie secara langsung. Ini lebih relevan terhadap pencurian session via XSS daripada fixation, tetapi tetap merupakan baseline penting karena serangan nyata sering berlapis.
SameSite
SameSite membantu mengurangi pengiriman cookie pada konteks lintas situs. Untuk banyak aplikasi, Lax adalah titik awal yang aman dan masih kompatibel. Strict lebih ketat tetapi dapat mengganggu alur navigasi tertentu. None hanya dipakai jika benar-benar butuh konteks lintas situs, dan harus disertai Secure.
Trade-off utamanya adalah kompatibilitas alur aplikasi. Pilih nilai yang sesuai kebutuhan, tetapi jangan menganggap SameSite sebagai pengganti rotasi session ID.
Cakupan domain dan path cookie
Jangan set domain cookie lebih luas dari yang diperlukan. Bila cookie session berlaku untuk terlalu banyak subdomain, risiko bertambah karena layanan lain di bawah domain yang sama bisa ikut memengaruhi konteks cookie. Gunakan Path sesempit yang masih praktis, dan hindari desain yang memungkinkan session lintas area yang tidak terkait.
Binding secukupnya ke konteks request
Beberapa aplikasi menambahkan pemeriksaan tambahan bahwa session harus konsisten dengan konteks request, misalnya kombinasi IP, User-Agent, geolokasi kasar, atau jejak perangkat. Pendekatan ini bisa membantu mendeteksi penyalahgunaan, tetapi jangan terlalu agresif.
Apa yang layak dibinding?
- User-Agent fingerprint ringan, misalnya normalisasi browser utama dan platform.
- IP prefix kasar atau perubahan ASN yang mencolok, bukan IP penuh secara kaku.
- Negara atau wilayah umum untuk deteksi anomali, bukan untuk blokir otomatis yang keras.
Mengapa harus secukupnya?
Jaringan seluler, VPN perusahaan, load balancer, dan pembaruan browser bisa membuat atribut request berubah walaupun pengguna sah. Jika binding terlalu ketat, pengguna akan sering ter-logout dan sistem malah sulit dipakai.
Praktik yang lebih aman adalah memakai binding ini sebagai sinyal risiko untuk memicu rotasi ulang, re-auth, atau logging tambahan, bukan satu-satunya syarat validitas session.
TTL session: idle timeout vs absolute timeout
Idle timeout
Idle timeout mengakhiri session setelah tidak ada aktivitas selama periode tertentu. Ini membatasi durasi penyalahgunaan jika cookie aktif terbuka atau session terpapar.
Absolute timeout
Absolute timeout memaksa session berakhir setelah total waktu tertentu sejak login, walaupun pengguna terus aktif. Ini mencegah session hidup terlalu lama.
Mengapa keduanya perlu?
Jika hanya ada idle timeout, session yang terus aktif dapat bertahan sangat lama. Jika hanya ada absolute timeout tanpa idle timeout, session yang ditinggalkan di perangkat bersama tetap valid terlalu lama. Kombinasi keduanya memberi kontrol yang lebih seimbang.
Untuk area sensitif seperti admin atau keuangan, gunakan batas yang lebih pendek dibanding area pengguna biasa. Namun pastikan timeout tidak memutus proses penting secara tiba-tiba tanpa mekanisme penyimpanan state yang memadai.
Logging dan deteksi anomali
Mitigasi pencegahan sebaiknya dilengkapi observabilitas. Session fixation sering sulit dibedakan dari penggunaan normal jika Anda tidak mencatat transisi session.
Event yang layak dicatat
- pembuatan session anonim,
- rotasi session setelah login,
- rotasi setelah perubahan privilege,
- logout dan invalidasi session,
- upaya memakai session yang sudah tidak valid,
- perubahan konteks request yang tidak biasa dalam waktu singkat.
Sinyal anomali yang berguna
- satu akun memakai session dari lokasi atau fingerprint yang sangat berbeda dalam jeda singkat,
- session lama tetap dipakai sesudah rotasi,
- frekuensi rotasi gagal atau invalidasi gagal meningkat,
- banyak percobaan akses dengan session ID yang tidak dikenal atau sudah kedaluwarsa.
Untuk alasan keamanan dan privasi, log sebaiknya menyimpan hash session ID, bukan nilainya secara utuh. Ini cukup untuk korelasi tanpa membuat log menjadi sumber kebocoran baru.
Kesalahan umum yang sering terjadi
- Tidak rotate session setelah autentikasi. Ini kesalahan nomor satu.
- Hanya rotate saat login, tetapi tidak saat privilege berubah.
- Membuat session baru tanpa menghapus yang lama.
- Menerima session ID dari URL. Session ID di URL mudah bocor lewat referer, log, history, atau bookmark.
- Cookie session tanpa Secure/HttpOnly/SameSite yang sesuai.
- Logout hanya di sisi klien. Menghapus cookie di browser saja tidak cukup jika session server-side masih valid.
- Binding terlalu kaku ke IP penuh. Ini sering memicu false positive dan pengalaman pengguna buruk.
- Tidak menguji perilaku cluster atau cache terdistribusi. Rotasi terlihat benar di lokal, tetapi gagal konsisten di produksi multi-node.
Checklist hardening session fixation
- Regenerasi session ID setelah login berhasil.
- Regenerasi session ID setelah MFA, re-auth, atau perubahan privilege.
- Invalidasi session lama segera setelah rotasi.
- Hapus session server-side saat logout, lalu hapus cookie di klien.
- Gunakan cookie session dengan
Secure,HttpOnly, danSameSiteyang tepat. - Batasi domain dan path cookie seperlunya.
- Jangan pernah menerima atau mengirim session ID lewat URL.
- Terapkan idle timeout dan absolute timeout yang sesuai tingkat sensitivitas.
- Gunakan binding ringan ke konteks request sebagai sinyal risiko, bukan aturan kaku.
- Hash session ID di log dan catat event rotasi/invalidation.
- Uji alur login, logout, dan perubahan role di lingkungan multi-instance.
- Pastikan sesi anonim tidak otomatis diwariskan menjadi sesi login tanpa rotasi.
Tips pengujian dan debugging
Uji manual sederhana
- Buka aplikasi sebagai pengguna anonim dan catat cookie session.
- Login dengan akun uji.
- Periksa apakah nilai cookie session berubah setelah login.
- Coba pakai session ID lama ke endpoint yang butuh autentikasi.
- Pastikan server menolak session lama.
Hal yang perlu diperiksa jika rotasi tidak bekerja
- Middleware session berjalan setelah atau sebelum middleware autentikasi secara tidak tepat.
- Proxy atau CDN men-cache respons yang berisi
Set-Cookie. - Ada lebih dari satu mekanisme session dan salah satunya masih mempertahankan ID lama.
- Store session terdistribusi belum menghapus session lama secara konsisten.
- Cookie lama tersisa karena domain/path berbeda dari cookie baru.
Debugging sering gagal karena tim hanya memeriksa browser, padahal masalah sebenarnya ada pada urutan middleware, cache proxy, atau perilaku store session.
Penutup
Mencegah session fixation di aplikasi web modern pada dasarnya bergantung pada satu prinsip: jangan pernah mempertahankan session ID yang sama ketika status keamanan pengguna berubah. Regenerasi session ID setelah login, logout, dan perubahan privilege harus dianggap sebagai baseline, bukan fitur tambahan.
Setelah itu, kuatkan dengan invalidasi session lama, cookie yang dikonfigurasi benar, timeout yang masuk akal, binding ringan ke konteks request, serta logging anomali. Dengan kombinasi ini, risiko fixation turun drastis dan perilaku session aplikasi menjadi jauh lebih dapat diprediksi serta lebih mudah diaudit.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!