XSS (Cross-Site Scripting) — одна из наиболее распространённых угроз в веб-разработке. Она возникает, когда злоумышленник внедряет вредоносный скрипт в веб-приложение через вводимые пользователем данные или параметры URL. В контексте библиотек маршрутизации, таких как Navigo, особое внимание уделяется безопасной обработке URL и параметров маршрутов.
При использовании Navigo маршруты часто принимают динамические параметры. Например:
const router = new Navigo('/');
router.on('/user/:id', (params) => {
console.log(params.id);
});
Если значение :id подставляется напрямую в DOM без
очистки, возникает риск XSS.
Для предотвращения внедрения скриптов необходимо всегда экранировать или фильтровать пользовательский ввод. Один из подходов — использовать безопасные функции для работы с текстом, выводимым на страницу:
function escapeHTML(str) {
return str
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
router.on('/user/:id', (params) => {
const safeId = escapeHTML(params.id);
document.getElementById('userId').textContent = safeId;
});
Здесь escapeHTML преобразует потенциально опасные
символы в безопасные HTML-сущности, исключая возможность выполнения
скриптов.
Navigo поддерживает использование регулярных выражений для валидации параметров. Это позволяет ограничивать значения строго ожидаемыми формами:
router.on('/product/:productId(\\d+)', (params) => {
console.log('Product ID:', params.productId);
});
В этом примере маршрут принимает только числовые идентификаторы.
Любые символы, не соответствующие \d+, будут автоматически
отвергнуты и не попадут в обработчик.
Помимо динамических сегментов маршрута, часто используются query-параметры. Их необходимо валидировать отдельно:
router.on('/search', () => {
const queryParams = new URLSearchParams(window.location.search);
const searchTerm = queryParams.get('q');
if (searchTerm) {
const safeTerm = escapeHTML(searchTerm);
document.getElementById('results').textContent = safeTerm;
}
});
Использование URLSearchParams гарантирует корректное
разбор query-строки, а дополнительное экранирование защищает от XSS
через параметры поиска.
Даже при использовании Navigo важно контролировать вставку данных в
атрибуты HTML. Прямое использование innerHTML с
динамическими значениями крайне опасно:
// Опасно
document.getElementById('content').innerHTML = params.id;
// Безопасно
document.getElementById('content').textContent = escapeHTML(params.id);
Для безопасного создания HTML-элементов лучше использовать методы
создания элементов через document.createElement и
appendChild, избегая конкатенации строк с HTML.
Navigo позволяет задавать fallback-маршруты и обрабатывать несуществующие пути. Это снижает риск XSS через случайные или некорректные URL:
router.notFound(() => {
document.getElementById('content').textContent = 'Страница не найдена';
});
Все неизвестные маршруты перенаправляются на безопасную заглушку, исключая возможность выполнения вредоносного кода.
При использовании hash-маршрутизации важно
контролировать символ # в URL. Даже если hash используется
для состояния приложения, нельзя напрямую вставлять его в DOM без
экранирования:
router.on('/page/:section', (params) => {
const section = escapeHTML(params.section);
document.getElementById('sectionTitle').textContent = section;
});
Любые спецсимволы, включая <script>, будут
безопасно преобразованы.
URLSearchParams.innerHTML и других методов, которые могут
выполнить скрипт.Правильное сочетание этих техник обеспечивает защиту от большинства XSS-атак, связанных с URL, в приложениях на базе Navigo.