Mencegah XSS
Prinsip utama pencegahan XSS: jangan pernah mempercayai input pengguna dan selalu encode/escape output sebelum ditampilkan.
1. Output Encoding
Encode semua data yang berasal dari pengguna sebelum memasukkannya ke HTML:
// JavaScript: gunakan textContent, bukan innerHTML
// BURUK — rentan XSS
element.innerHTML = userInput;
// BAIK — aman dari XSS
element.textContent = userInput;
// Jika harus menggunakan innerHTML, sanitize terlebih dahulu
import DOMPurify from "dompurify";
element.innerHTML = DOMPurify.sanitize(userInput);
2. PHP htmlspecialchars()
Di PHP native, gunakan htmlspecialchars() untuk meng-escape output HTML:
// PHP: escape output manual
echo htmlspecialchars($userInput, ENT_QUOTES, "UTF-8");
Di Laravel, Blade template {{ $variable }} secara otomatis memanggil htmlspecialchars(), sehingga output sudah di-escape secara default.
3. Framework Auto-Escaping
Framework modern secara default melakukan escaping:
// React — auto-escape by default
function Greeting({ name }) {
return <h1>Halo, {name}</h1>; // Aman!
}
// <script> tags akan di-escape menjadi teks biasa
// BAHAYA: dangerouslySetInnerHTML melewati escaping
<div dangerouslySetInnerHTML={{ __html: userInput }} /> // JANGAN!
// Laravel Blade — auto-escape by default
{{ $userInput }} // Aman — di-escape
{!! $userInput !!} // BAHAYA — raw HTML, jangan untuk user input
3. Content Security Policy (CSP)
Header HTTP yang membatasi sumber script yang boleh dijalankan:
// Hanya izinkan script dari domain sendiri
Content-Security-Policy: script-src 'self'
// Dengan nonce untuk inline script
Content-Security-Policy: script-src 'nonce-abc123'
<script nonce="abc123">
// Script ini diizinkan
</script>
Context-Aware Encoding
Encoding yang tepat tergantung di mana data ditempatkan:
- HTML body — HTML entity encoding (
<,>, dll.) - HTML attribute — Attribute encoding
- JavaScript — JavaScript encoding
- URL — URL encoding (
encodeURIComponent) - CSS — CSS encoding
Library Sanitization
// DOMPurify — library populer untuk sanitasi HTML
import DOMPurify from "dompurify";
const clean = DOMPurify.sanitize(dirty, {
ALLOWED_TAGS: ["b", "i", "em", "strong", "a"],
ALLOWED_ATTR: ["href"]
});
Checklist Anti-XSS
- Gunakan framework yang auto-escape output
- Jangan gunakan
innerHTML,dangerouslySetInnerHTML, atau{!! !!}dengan user input - Implementasikan Content Security Policy
- Gunakan DOMPurify jika harus menerima HTML dari user
- Set cookie dengan flag HttpOnly