FlawOpen

flawopen.com/Vulnerabilities/Session Fixation dan Keamanan Cookie

Session Fixation: Ganti ID saat Login (CWE-384)

High Severity CWE-384 Cryptography & Auth
💡 Penjelasan sederhana — tiket bagasi yang ditempel

Bayangkan seorang pelancong dibujuk memakai nomor tiket bagasi yang sudah diketahui penyerang. Jika maskapai tetap memakai nomor itu setelah bagasi diserahkan, penyerang mungkin dapat mengambil koper tersebut. Pada session fixation, aplikasi menerima identifier yang dapat dipaksakan penyerang agar dipakai korban, lalu mengubah identifier yang sama menjadi sesi terautentikasi tanpa menggantinya. Kedua kondisi ini harus terpenuhi; tautan phishing biasa saja tidak menetapkan sesi kecuali aplikasi menerima atau mengizinkan identifier tersebut diatur.

Target: pengelolaan sesi di server dan identifier yang digunakan browser terautentikasi.
Prasyarat: penyerang dapat membuat korban memakai ID sesi yang diketahui, misalnya melalui ID URL yang diterima aplikasi atau injeksi cookie.
Kegagalan: aplikasi mempertahankan ID yang diketahui penyerang saat sesi anonim berubah menjadi sesi terautentikasi.
Perbaikan: terbitkan ID baru yang sulit ditebak saat autentikasi; atur atribut cookie untuk ancaman yang berbeda.

Konsep inti dan istilah subsistem

Session fixation
Cacat pengelolaan sesi ketika aplikasi menerima identifier yang diketahui penyerang dan mempertahankannya setelah korban masuk.
Rotasi ID sesi
Terbitkan identifier baru yang sulit ditebak ketika autentikasi meningkatkan hak sesi. Pertahankan hanya data sesi yang memang perlu disimpan aplikasi.
Atribut cookie
Secure membatasi pengiriman cookie ke HTTPS; HttpOnly mencegah JavaScript membaca cookie; SameSite mengatur sebagian pengiriman lintas situs. Ketiganya menangani risiko berbeda dan tidak menggantikan rotasi ID.
Prefix __Host-
Pada browser yang mendukungnya, prefix ini mewajibkan cookie Secure yang disetel melalui HTTPS, memakai Path=/, dan tanpa atribut Domain. Ini membantu mencegah subdomain saudara membuat cookie bernama sama untuk domain induk.

Alur serangan langkah demi langkah

Step 1

Penyerang memperoleh atau memilih identifier sesi

Kelemahan atau fitur lain memungkinkan penyerang memperoleh ID dan membuat browser korban mengirimkannya. Jalurnya bergantung pada aplikasi; tautan phishing biasa tidak cukup bila ID sesi di URL ditolak.

Step 2

Korban memakai identifier yang diketahui penyerang

Browser mengirim ID itu ke aplikasi, yang menganggapnya sebagai sesi anonim valid. Penyerang harus dapat mengenali atau memakai kembali identifier yang sama.

Step 3

Autentikasi menaikkan hak sesi

Korban masuk. Jika aplikasi mengaitkan identitas terautentikasi ke ID lama tanpa menggantinya, identifier yang diketahui itu kini menunjuk ke sesi terautentikasi.

Step 4

Penyerang menggunakan kembali identifier yang tidak berubah

Jika penyerang masih dapat mengirim ID dan server belum membatalkannya, penyerang mungkin mengakses sesi korban. Rotasi ID saat perubahan hak memutus rantai ini.

Mekanisme dan akar masalah

Session fixation memerlukan dua hal: penyerang memengaruhi identifier yang dipakai korban dan aplikasi tidak menggantinya setelah login berhasil. Atribut cookie memberi pertahanan berlapis, tetapi tidak menggantikan rotasi ID: HttpOnly membatasi pembacaan oleh skrip, Secure mewajibkan HTTPS, SameSite mengurangi sebagian pengiriman lintas situs, dan __Host- membatasi cakupan cookie di browser yang mendukungnya.

login_view.py (Pola rentan)Rentan
# VULNERABLE: custom session code keeps the pre-authentication ID.
def login_view(request):
    user = authenticate(request, request.POST["username"],
                        request.POST["password"])
    if user is not None:
        # BUG: privilege changes, but the session ID does not.
        request.session["user_id"] = user.pk
        request.session["authenticated"] = True
        return redirect("/account/")
    return redirect("/login/")
login_view.py (Contoh Django aman)Diperkuat
# HARDENED: Django login() rotates the session key on authentication.
from django.contrib.auth import authenticate, login

def login_view(request):
    user = authenticate(request, request.POST["username"],
                        request.POST["password"])
    if user is not None:
        # Uses Django's supported authentication/session integration.
        login(request, user)
        return redirect("/account/")
    return redirect("/login/")

# settings.py: use HTTPS, host-only scope, and a deliberate SameSite policy.
SESSION_COOKIE_NAME = "__Host-sessionid"
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Lax"
SESSION_COOKIE_PATH = "/"
SESSION_COOKIE_DOMAIN = None

Urutan serangan dan contoh konseptual

Aturan pencegahan dan penguatan engineering

Sumber dan topik keamanan terkait:Direktori Keamanan Lengkap →
CWE-384: Session Fixation → OWASP: Panduan Pengelolaan Sesi → OWASP WSTG: Pengujian Session Fixation → Django: Sesi dan cycle_key() → MDN: Cookie HTTP dan prefix →