FlawOpen

flawopen.com/XSS in JavaScript/DOMPurify and innerHTML

Apakah DOMPurify cukup untuk mengamankan innerHTML?

Panduan referensi
Jawaban singkat

DOMPurify adalah sanitizer allow-list yang kuat untuk rich HTML jika hasilnya langsung masuk ke sink HTML tanpa diubah lagi. Ibarat paket yang diperiksa di pintu gudang: bila proses lain mengemas ulang atau memasukkannya lewat pintu lain, pemeriksaan awal tidak lagi mencakup isi akhirnya. Untuk teks biasa, gunakan textContent agar HTML tidak diparse.

MASIH BERISIKO — hasil lama masuk ke sink
// Disanitasi saat disimpan dengan versi/kebijakan lama.
saveToDb(DOMPurify.sanitize(input));

// Kode kemudian mempercayai string tersimpan tanpa pemeriksaan.
el.innerHTML = fetchedFromDb;
LEBIH AMAN — sanitasi untuk sink HTML ini
// Jika perlu rich HTML, sanitasi dengan library terbaru
// tepat sebelum memasukkannya ke konteks HTML.
el.innerHTML = DOMPurify.sanitize(untrustedHtml, {
  USE_PROFILES: { html: true },
});

// Untuk teks biasa, jangan parse sebagai HTML.
textNode.textContent = untrustedText;

Mengapa sanitasi sekali saat menyimpan lebih lemah

Sanitasi saat menyimpan tidak otomatis rentan, tetapi menciptakan batas data usang: renderer dapat mempercayai output lama setelah perbaikan sanitizer, perubahan kebijakan, atau jalur yang melewatkan sanitasi. Sanitasi ulang saat rendering dengan versi terbaru dan kebijakan untuk sink yang tepat. Jangan ubah markup bersih atau meneruskannya ke library lain sebelum disisipkan; post-processing dapat membatalkan hasil sanitasi.

Konfigurasi dan konteks output penting

Konfigurasi bawaan DOMPurify mengizinkan HTML, SVG, dan MathML. Jika hanya perlu HTML, batasi profil dengan USE_PROFILES: { html: true }. Jangan memperluas tag atau atribut tanpa peninjauan. DOMPurify bukan sanitizer CSS dan tidak mencegah semua permintaan sumber eksternal; gunakan hasil hanya di konteks HTML, jangan pakai ulang di JavaScript, atribut, XML, SVG, atau CSS.

Trusted Types dan rendering sisi server

Jika didukung, wajibkan Trusted Types lewat Content Security Policy agar string ke sink HTML ditolak kecuali melewati policy yang disetujui. DOMPurify dapat menghasilkan TrustedHTML; ini mengurangi penggunaan sink yang tidak sengaja, tetapi tidak memperbaiki konfigurasi atau post-processing yang tidak aman. Di server, DOMPurify bergantung pada implementasi DOM: perbarui jsdom dan jangan padukan dengan happy-dom untuk sanitasi sensitif keamanan.

Daftar periksa produksi

Cari sink injeksi HTML

rg -n -g '*.{js,ts,jsx,tsx}' '(innerHTML|outerHTML|insertAdjacentHTML|document\.write|dangerouslySetInnerHTML)' .
Untuk setiap hasil, lacak data tak tepercaya hingga sink, pastikan sanitasi tepat sebelum penyisipan, dan periksa agar kode setelahnya tidak mengubah markup.

Sumber dan referensi

Lihat juga Cross-Site Scripting (XSS, CWE-79): cara kerja dan cara mencegahnya di setiap bahasa — flawopen.com Apakah rendering Markdown aman dari XSS? Apakah Svelte aman dari XSS secara default? Apakah unggahan SVG berisiko XSS? Risiko XSS pada Vue v-html WKWebView: HTML tak tepercaya aman? Apa beda XSS reflected, stored, dan DOM-based?