XSS-атаки и их предотвращение

XSS (Cross-Site Scripting) — это уязвимость веб-приложений, при которой злоумышленник может внедрить и выполнить вредоносный скрипт в контексте браузера пользователя. XSS позволяет:

  • Красть данные сессии и аутентификационные токены.
  • Подменять контент страницы.
  • Выполнять действия от имени пользователя.
  • Перенаправлять пользователей на вредоносные ресурсы.

Существует три основных типа XSS: Reflected, Stored и DOM-based.

  1. Reflected XSS — вредоносный скрипт передаётся через URL или форму и немедленно возвращается сервером в ответ.
  2. Stored XSS — скрипт сохраняется на сервере (в базе данных, комментариях, профилях) и выполняется при отображении контента.
  3. DOM-based XSS — скрипт внедряется через клиентские операции с DOM без участия сервера.

Механизмы внедрения

XSS-атаки используют возможности браузера по интерпретации HTML и JavaScript. Основные векторы:

  • Ввод пользовательских данных в форму без фильтрации (<input>).
  • Параметры URL, вставляемые в страницу без экранирования.
  • Использование innerHTML или document.write для динамического контента.
  • Обработка данных из localStorage или cookies без проверок.

Пример опасного кода на Jav * aScript:

const userInput = location.search.split('name=')[1];
document.getElementById('greeting').innerHTML = `Привет, ${userInput}!`;

Если userInput содержит <script>alert('XSS')</script>, скрипт выполнится.

Принципы предотвращения XSS

1. Экранирование данных

Все данные, выводимые в HTML, должны быть экранированы. Это предотвращает интерпретацию специальных символов браузером. Примеры:

  • &&amp;
  • <&lt;
  • >&gt;
  • "&quot;
  • '&#x27;

В JavaScript безопаснее использовать методы, работающие с текстом, а не HTML:

document.getElementById('greeting').textContent = userInput;

2. Использование строгого контекста

В HTML, JavaScript, CSS и URL есть свои контексты, в которых XSS проявляется по-разному. Для каждого контекста применяются отдельные правила:

  • HTML-текст: использовать textContent вместо innerHTML.
  • Атрибуты: использовать setAttribute и экранировать специальные символы.
  • URL: проверять схему и кодировать параметры через encodeURIComponent.
  • CSS: избегать динамических вставок через style или фильтровать значения.

3. Content Security Policy (CSP)

CSP позволяет ограничить источники выполнения скриптов и загрузки ресурсов. Пример строгой политики:

Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none';

Это блокирует выполнение встроенных скриптов и подключение внешних, предотвращая многие виды XSS.

4. Валидация и фильтрация данных

  • Серверная проверка обязательна даже при наличии клиентских фильтров.
  • Фильтруются опасные теги (<script>, <iframe>), атрибуты (onload, onclick) и протоколы (jav * ascript:).
  • Используются белые списки разрешённых тегов и атрибутов.

Защита в контексте библиотек типа Umbrella JS

Umbrella JS предоставляет лёгкий API для работы с DOM. При использовании функций библиотеки необходимо учитывать XSS-риски:

1. Вставка текста

Методы .text() безопасны для вывода пользовательских данных:

u('#greeting').text(userInput);

Это автоматически экранирует все специальные символы.

2. Вставка HTML

Метод .html() позволяет вставлять HTML, но не фильтрует опасные скрипты:

u('#content').html('<p>' + userInput + '</p>'); // Опасно!

Если вставляется контент от пользователя, нужно использовать сторонние функции для очистки или ограничивать допустимые теги.

3. Манипуляции с атрибутами

u('a.link').attr('href', safeUrl);

При установке URL следует проверять схему и кодировать параметры.

4. События

Подключение обработчиков через Umbrella JS безопаснее, чем вставка onclick в HTML:

u('#button').on('click', () => {
    console.log('Кнопка нажата');
});

Прямое использование HTML-атрибутов событий уязвимо к XSS.

Практические рекомендации

  • Никогда не доверять пользовательскому вводу.
  • Использовать методы .text() вместо .html(), когда это возможно.
  • При работе с .html() применять проверку и очистку данных.
  • Валидировать URL и данные перед вставкой в атрибуты.
  • Настроить CSP для ограничения внешних скриптов.
  • Периодически проверять приложение на XSS с помощью автоматических сканеров и ручного тестирования.

Эти меры формируют многослойную защиту, минимизируют риск XSS и повышают устойчивость веб-приложения к атакам.