Stored vs Reflected vs DOM XSS — Security

Tiga Tipe XSS XSS dibagi menjadi tiga tipe berdasarkan cara payload disimpan dan dieksekusi. Memahami perbedaannya penting untuk strategi pencegahan yang…

XSS dibagi jadi tiga tipe: Stored, Reflected, dan DOM-based. Bedanya cuma di dua pertanyaan: teks yang gak bisa dipercaya itu datang dari mana, dan siapa yang menaruhnya ke halaman. Bayangin tukang ledeng yang datang ke rumah dengan pipa bocor. Pertanyaan pertamanya selalu: airnya masuk dari mana, dan keluar di mana? Jawaban itu yang menentukan bagian mana yang diperbaiki. XSS juga begitu.

🧪 Tebakan cepat: di DOM-based XSS, apakah escape di template server bisa menolong? Jawabannya ada di bagian "DOM-based XSS".

Source dan sink

Lab memakai tiga contoh yang sama dengan materi ini, masing-masing dengan teks yang gak bisa dipercaya sebagai datanya.

Stored XSS

Data disimpan dulu, lalu ditampilkan ke setiap orang yang membuka halamannya. Contohnya komentar di database yang dicetak oleh Blade:

{{-- rentan: komentar dari database dicetak mentah --}}
<p>{!! $comment->body !!}</p>

{{-- perbaikan: di-escape saat ditampilkan --}}
<p>{{ $comment->body }}</p>

Reflected XSS

Data datang dari request dan langsung dipantulkan ke response, tanpa disimpan. Contohnya halaman pencarian:

// rentan: kata kunci dari URL disalin mentah ke HTML
res.send("<p>Hasil pencarian untuk: " + req.query.q + "</p>");

// perbaikan: di-escape dulu
res.send("<p>Hasil pencarian untuk: " + sanitizeHTML(req.query.q) + "</p>");

DOM-based XSS

Di sini server gak ikut menyusun HTML-nya. JavaScript di browser membaca data dari URL, lalu menaruhnya ke halaman:

const pesan = new URLSearchParams(location.search).get("pesan");

// rentan: dibaca sebagai HTML
document.getElementById("pesan").innerHTML = pesan;

// perbaikan: selalu jadi teks
document.getElementById("pesan").textContent = pesan;

Perbandingan

Tipe Source Sink Yang kena Perbaikan
Stored database template server setiap pengunjung escape saat ditampilkan
Reflected parameter request response server yang membuka URL itu escape di server
DOM-based URL, dibaca JavaScript innerHTML yang membuka URL itu textContent di JavaScript

⚠️ Jebakan yang sering ketemu

TL;DR: Tiga tipe XSS dibedakan dari source dan sink-nya. Stored XSS: data tersimpan di database dan tercetak mentah, mengenai setiap pengunjung; perbaiki dengan escape saat ditampilkan ({{ }} di Blade). Reflected XSS: data dari URL atau form langsung dipantulkan server, mengenai yang membuka URL itu; perbaiki dengan escape di server. DOM-based XSS: JavaScript di browser menaruh data dari URL lewat innerHTML, tanpa server ikut menyusun HTML-nya; perbaiki di JavaScript dengan textContent.

Yang akan kamu pelajari