flawopen.com/XSS в JavaScript/Vue v-html
Риск XSS при использовании Vue v-html
Интерполяция Vue {{ comment }} похожа на записку за стеклом: угловые скобки остаются текстом. v-html просит браузер интерпретировать записку как HTML. Если разметкой управляет пользователь, браузер может принять её за структуру страницы или активное содержимое, создав риск XSS.
<p v-html="comment"></p>
// comment интерпретируется как настоящая разметка
<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>
Очищайте rich HTML перед v-html
Используйте интерполяцию Vue {{ }}, если содержимое должно быть текстом. Если функция действительно требует пользовательский rich HTML, очищайте его поддерживаемой библиотекой, например DOMPurify, с узким списком разрешённого; привязывайте к v-html только очищенный результат. Обновляйте санитайзер и тестируйте разрешённую разметку. Очистка снижает риск, но не делает любой HTML безопасным во всех контекстах; используйте изолированный iframe, если активное содержимое должно оставаться недоверенным. Vue не компилирует содержимое v-html как Vue-шаблон.
Проверьте v-html и проследите поток данных
Найдите все привязки v-html. Для каждой установите источник, санитайзер и его конфигурацию, а также круг пользователей, которые увидят вывод. Отметьте прямой пользовательский ввод, сохранённые комментарии, поля CMS и ответы API; убедитесь, что обычный текст выводится через интерполяцию.
grep -rn "v-html" --include="*.vue" .Частые вопросы
Оба способа обходят обычное экранирование текста фреймворком и вставляют HTML в DOM. Для необходимого rich HTML используйте поддерживаемый санитайзер и не считайте очищенный результат универсально безопасным.
Источники
- Vue.js — Безопасность: HTML-содержимое
- DOMPurify — документация HTML-санитайзера
- OWASP — предотвращение Cross-Site Scripting
- flawopen.com — XSS в JavaScript