XSS и v-html
↑ 7.3 Безопасность фронтенда · → Следующая
Зачем это на собесе
XSS — главная фронтенд-уязвимость. Нужно различать виды, знать защиту во Vue и опасные места.
Что это
Cross-Site Scripting: злоумышленник внедряет свой JS на страницу, и тот выполняется от имени сайта — с доступом к cookies, localStorage, DOM и запросам пользователя.
Виды
| Вид | Откуда payload |
|---|---|
| Stored | сохранён на сервере (комментарий, профиль) |
| Reflected | из URL или формы, возвращается в ответе |
| DOM-based | клиентский код сам вставляет данные небезопасно (innerHTML, location.hash) |
Защита во Vue
Интерполяция {{ }} и :attr экранируются автоматически. Опасны:
v-html— вставляет сырой HTML;innerHTML,insertAdjacentHTML,document.write;- динамические
href/srcсо значениемjavascript:...; - шаблоны, собираемые из пользовательских строк (
compileна клиенте); eval,new Function,setTimeout(string).
<!-- опасно, если html приходит от пользователя -->
<div v-html="comment.html" />
<!-- безопасно -->
<div>{{ comment.text }}</div>Санитизация
Если нужен HTML (редактор, markdown), очищаем DOMPurify с белым списком:
import DOMPurify from 'dompurify'
const clean = DOMPurify.sanitize(dirty, { ALLOWED_TAGS: ['b', 'i', 'a', 'ul', 'li', 'p'], ALLOWED_ATTR: ['href'] })Санитизировать нужно там, где рендерим (и на сервере при сохранении как второй слой).
Слои защиты
- Экранирование по умолчанию, отказ от
v-html. - Санитизация HTML (DOMPurify).
- CSP — запрет inline-скриптов.
- Cookie токена с
HttpOnly. - Валидация URL: только
http(s):. - Trusted Types (Chrome) для DOM-приёмников.
Вопросы с ответами
Защищает ли Vue от XSS?
В шаблонах экранирует данные, но
v-html,innerHTMLиjavascript:-ссылки остаются на ответственности разработчика.
Как безопасно показать HTML от пользователя?
Пропустить через DOMPurify с белым списком тегов и атрибутов, дополнительно ограничить CSP.