XSS и v-html

↑ 7.3 Безопасность фронтенда · → Следующая

Желательно~3 мин чтенияУровень: senior

Зачем это на собесе

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'] })

Санитизировать нужно там, где рендерим (и на сервере при сохранении как второй слой).

Слои защиты

  1. Экранирование по умолчанию, отказ от v-html.
  2. Санитизация HTML (DOMPurify).
  3. CSP — запрет inline-скриптов.
  4. Cookie токена с HttpOnly.
  5. Валидация URL: только http(s):.
  6. Trusted Types (Chrome) для DOM-приёмников.

Вопросы с ответами