Website kamu menerima data dari luar: isi form, URL, cookie. Penyerang (orang yang sengaja mencari celah) memakai jalan masuk itu untuk menyusupkan kode atau menyamar jadi pengguna lain. Ini serangan paling dasar di web, dan cara menangkal masing-masing.
🧪 Tebakan cepat: kamu menulis komentar
<b>halo</b>di situs yang aman. Yang tampil "halo" bercetak tebal, atau teks<b>halo</b>apa adanya? Jawabannya ada di bagian "XSS: komentar yang berubah jadi kode".
XSS: komentar yang berubah jadi kode
XSS (Cross-Site Scripting) terjadi saat teks dari pengguna masuk ke halaman apa adanya, lalu browser membacanya sebagai HTML. Misalnya server menyusun halaman dari komentar ini:
<!-- Komentar dimasukkan apa adanya -->
<p class="komentar"><script>alert(document.cookie)</script></p>
<!-- Komentar di-escape dulu -->
<p class="komentar"><script>alert(document.cookie)</script></p>
- Di baris pertama, browser melihat tag
<script>sungguhan dan menjalankannya, di browser setiap orang yang membuka halaman itu. - Baris kedua sudah di-escape: karakter yang punya arti di HTML diganti kodenya.
<jadi<,>jadi>,&jadi&, tanda kutip jadi". - Browser menampilkan
<sebagai karakter<biasa. Komentarnya tampil sebagai teks, dan gak ada yang jalan.
Jadi jawaban tebakannya: teks <b>halo</b> apa adanya. Di JavaScript, elemen.textContent = komentar selalu memasukkan teks, sedangkan innerHTML membacanya sebagai HTML. Lapisan kedua adalah header CSP (Content-Security-Policy), yang memberi tahu browser script dari mana saja yang boleh jalan.
CSRF: request palsu atas nama kamu
Saat kamu login, browser menyimpan cookie (catatan kecil dari server) dan mengirimnya otomatis di setiap request ke situs itu. CSRF (Cross-Site Request Forgery) memanfaatkan itu:
1. Kamu login ke bank.contoh, browser menyimpan cookie login.
2. Kamu membuka situs-jahat.contoh di tab lain.
3. Situs itu diam-diam mengirim form transfer ke bank.contoh.
4. Cookie login kamu ikut terkirim, jadi bank mengira itu kamu.
Penangkalnya CSRF token: kode acak rahasia yang server taruh di setiap form miliknya. Request tanpa token yang benar ditolak, dan situs lain gak bisa membaca token itu. Tambahannya, cookie dengan SameSite=Lax atau Strict gak ikut terkirim saat situs lain mengirim form ke situsmu.
Bedanya dengan XSS: XSS menyusupkan script ke halaman, CSRF memalsukan request dari pengguna yang sedang login.
SQL Injection: input yang ikut jadi perintah
SQL adalah bahasa untuk bertanya ke database. SQL Injection terjadi saat input pengguna digabung langsung ke query, sehingga penyerang bisa mengubah perintahnya:
// Bahaya: input ditempel langsung ke query
const query = "SELECT * FROM users WHERE name = '" + nama + "'";
// Aman: parameterized query, input dikirim terpisah
db.query("SELECT * FROM users WHERE name = ?", [nama]);
Kalau nama diisi ' OR 1=1 --, query pertama jadi "ambil user yang namanya kosong atau 1=1". 1=1 selalu benar, jadi semua user keluar. Di parameterized query, database mengisi ? sebagai data, bukan bagian perintah.
HTTPS dan HSTS
HTTPS mengenkripsi semua yang lewat antara browser dan server, jadi orang di Wi-Fi yang sama gak bisa membaca atau mengubahnya. Supaya browser gak pernah kembali ke http://, server mengirim header HSTS (HTTP Strict Transport Security):
Strict-Transport-Security: max-age=31536000; includeSubDomains
Artinya: selama setahun (31.536.000 detik), buka domain ini dan subdomainnya lewat HTTPS saja, walau pengguna mengetik http://.
⚠️ Jebakan yang sering ketemu
- Cuma menghapus kata
<script>.<img src="x" onerror="...">menjalankan kode tanpa tag script. Escape semua teks dari pengguna. - Validasi cuma di browser. Penyerang bisa mengirim request langsung tanpa lewat form kamu. Periksa ulang di server.
- Pesan error lengkap di production. Nama tabel dan isi query membantu penyerang. Tampilkan pesan umum, simpan detailnya di log.
- Cookie login tanpa flag. Pasang
HttpOnly(gak bisa dibaca JavaScript),Secure(cuma lewat HTTPS), danSameSite. Chrome dan Edge memakaiLaxkalau kamu gak menulisnya, browser lain belum tentu.
📌 Header keamanan lain
| Header | Yang dicegah |
|---|---|
Content-Security-Policy: script-src 'self' |
script dari domain lain jalan di halamanmu |
X-Frame-Options: DENY |
halamanmu dimuat diam-diam di iframe situs lain (clickjacking) |
X-Content-Type-Options: nosniff |
browser menebak jenis file, lalu menjalankan file teks sebagai script |
TL;DR: Jangan pernah percaya input pengguna. XSS menyusupkan script ke halaman: escape semua output dan pasang CSP. CSRF memalsukan request dari pengguna yang sedang login: pakai CSRF token dan cookie SameSite. SQL Injection menempelkan input ke query: pakai parameterized query. Pakai HTTPS, plus header Strict-Transport-Security (HSTS) supaya browser gak pernah kembali ke http://.