flawopen.com/XSS pada JavaScript/Vue v-html
Risiko XSS pada Vue v-html
Interpolasi Vue {{ comment }} seperti menampilkan catatan kutipan di balik kaca: tanda kurung sudut tetap menjadi teks. v-html meminta browser membuka catatan sebagai HTML. Jika markup dikendalikan pengguna, browser dapat memprosesnya sebagai struktur halaman atau konten aktif sehingga menimbulkan risiko XSS.
<p v-html="comment"></p>
// comment diproses sebagai markup sungguhan
<script setup>
import { computed } from 'vue'
import DOMPurify from 'dompurify'
const props = defineProps({ comment: String })
const safeComment = computed(() =>
DOMPurify.sanitize(props.comment ?? '', {
ALLOWED_TAGS: ['p', 'strong', 'em'],
ALLOWED_ATTR: []
})
)
</script>
<template>
<div v-html="safeComment"></div>
</template>
Sanitasi rich HTML sebelum v-html
Utamakan interpolasi Vue {{ }} jika konten seharusnya berupa teks. Jika fitur benar-benar memerlukan rich HTML buatan pengguna, sanitasi dengan library terawat seperti DOMPurify dan allowlist yang sempit; hanya ikat hasil yang sudah disanitasi ke v-html. Perbarui sanitizer dan uji kebijakan markup yang diizinkan. Sanitasi mengurangi risiko, tetapi tidak membuat semua HTML aman dalam setiap konteks; gunakan iframe terisolasi jika konten aktif harus tetap tidak tepercaya. Vue tidak mengompilasi konten v-html sebagai template Vue.
Audit v-html dan telusuri aliran data
Cari semua binding v-html. Untuk tiap temuan, identifikasi sumber, sanitizer beserta konfigurasinya, dan siapa yang dapat melihat konten hasil render. Tandai input langsung dari pengguna, komentar tersimpan, kolom CMS, dan respons API; pastikan teks biasa memakai interpolasi.
grep -rn "v-html" --include="*.vue" .Pertanyaan umum
Keduanya melewati jalur escape teks normal framework dan memasukkan HTML ke DOM. Gunakan sanitizer terawat jika rich HTML memang diperlukan, dan jangan menganggap hasil sanitasi aman di semua konteks.
Referensi
- Vue.js — Keamanan: Konten HTML
- DOMPurify — dokumentasi sanitizer HTML
- OWASP — pencegahan Cross-Site Scripting
- flawopen.com — XSS pada JavaScript