XSS и защита от инъекций

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

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

Каждый тип требует особого подхода к защите, но общий принцип предотвращения XSS — никогда не доверять пользовательскому вводу и всегда экранировать или фильтровать его перед выводом.


Роль библиотеки Cash

Cash — это компактная альтернатива jQuery, предоставляющая удобные методы для работы с DOM, событиями и AJAX. В контексте XSS защита становится особенно актуальной, так как неправильное использование методов вставки HTML может позволить злоумышленнику внедрить скрипт.


Безопасное добавление содержимого в DOM

Основное правило: никогда не использовать методы вставки HTML с необработанными данными.

В Cash доступны следующие методы для вставки содержимого:

  • html(content) — вставляет HTML в элемент. Если content содержит пользовательский ввод, он может стать источником XSS.
  • text(content) — вставляет текст, экранируя HTML. Этот метод безопасен для пользовательского ввода.
  • append(content) и prepend(content) — добавляют элементы внутрь выбранного узла. Использование с HTML-кодом требует тщательной фильтрации.

Пример безопасного использования:

const userInput = '<script>alert("XSS")</script>';
$('.output').text(userInput); // отобразится как текст, скрипт не выполнится

Опасный пример:

const userInput = '<script>alert("XSS")</script>';
$('.output').html(userInput); // скрипт выполнится

Методы text() и val() экранируют потенциально опасные символы (<, >, &, ", '), предотвращая исполнение скриптов.


Работа с атрибутами

Установка атрибутов через attr() может быть уязвимой, если передаются данные без проверки. Особое внимание следует уделять:

  • href — злоумышленник может вставить jav * ascript: URI.
  • src — может указывать на внешние скрипты.
  • onclick, onmouseover и другие обработчики событий.

Безопасная установка:

$('.link').attr('href', encodeURI(userInput)); // кодирует URI

Использование encodeURI или encodeURIComponent снижает риск XSS через URL.


Фильтрация и экранирование

Для защиты от XSS необходимо:

  1. Экранировать HTML-символы при выводе в текстовом контексте.
  2. Проверять допустимые значения перед вставкой в атрибуты или URL.
  3. Использовать шаблонизаторы, которые автоматически экранируют данные.
  4. Ограничивать ввод на клиенте и сервере, например через регулярные выражения.

Пример функции экранирования HTML:

function escapeHTML(str) {
    return str
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;');
}

$('.output').html(escapeHTML(userInput));

События и динамическое содержимое

При добавлении динамических элементов, к которым привязаны события через on() или click(), важно избегать внедрения inline-скриптов.

Безопасный подход через делегирование:

$(document).on('click', '.dynamic-button', function() {
    console.log('Кнопка нажата');
});

Даже если кнопка создаётся динамически с пользовательскими данными, обработчик безопасен, так как выполняется только код, определённый разработчиком, а не содержимое innerHTML.


Работа с AJAX

Cash предоставляет метод $.ajax() для выполнения HTTP-запросов. При получении данных с сервера необходимо всегда:

  • Проверять тип данных (dataType: 'json' для JSON).
  • Не вставлять данные напрямую в HTML без экранирования.
  • Использовать text() для вывода текстовой информации.

Пример безопасного вывода данных с сервера:

$.ajax({
    url: '/api/users',
    dataType: 'json',
    success: function(data) {
        data.forEach(user => {
            $('.users-list').append(
                $('<li>').text(user.name) // безопасно
            );
        });
    }
});

Итоговые принципы безопасного использования Cash

  • Использовать text() вместо html() для пользовательского ввода.
  • Экранировать все данные перед вставкой в DOM.
  • Проверять и кодировать атрибуты URL и ссылки.
  • Применять делегирование событий вместо inline-обработчиков.
  • Обрабатывать данные AJAX через безопасные методы.

Следование этим принципам обеспечивает надежную защиту от большинства атак XSS при работе с библиотекой Cash.