Navigo — это легковесный роутер для JavaScript, позволяющий управлять маршрутами в одностраничных приложениях (SPA). Одним из ключевых аспектов безопасного и предсказуемого поведения роутера является корректная обработка параметров маршрутов. Санитизация параметров помогает предотвратить ошибки при передаче данных в URL, а также снижает риски XSS-атак и других уязвимостей.
В Navigo параметры маршрута задаются с помощью двоеточия
:. Например:
router.on('/user/:id', (params) => {
console.log(params.id);
});
Здесь :id — динамический параметр. Когда пользователь
переходит по URL /user/42, объект params будет
содержать { id: "42" }.
Важно: По умолчанию Navigo передает параметры как строки, без какой-либо фильтрации или преобразования. Поэтому крайне важно санитизировать входящие значения перед использованием их в приложении.
Для числовых идентификаторов следует использовать преобразование в число и проверку:
const userId = Number(params.id);
if (isNaN(userId) || userId <= 0) {
// Некорректный параметр
router.navigate('/error');
return;
}
Для строковых параметров можно ограничить длину и разрешённые символы:
const username = params.username;
const sanitizedUsername = username.replace(/[^a-zA-Z0-9_-]/g, '');
if (sanitizedUsername.length === 0) {
router.navigate('/error');
}
Если параметр будет вставляться в DOM, необходимо экранировать специальные символы:
function escapeHTML(str) {
return str
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
const safeUsername = escapeHTML(params.username);
document.querySelector('#username').textContent = safeUsername;
Navigo позволяет задавать регулярные выражения для параметров, чтобы сразу ограничивать допустимые значения:
router.on('/user/:id(\\d+)', (params) => {
console.log('Пользователь с ID', params.id);
});
Здесь маршрут будет срабатывать только если :id содержит
только цифры.
Для удобства можно создать функцию-обёртку, которая автоматически проверяет все параметры перед вызовом обработчика:
function sanitizeParams(params, schema) {
const result = {};
for (const key in schema) {
const rule = schema[key];
const value = params[key];
if (rule.type === 'number') {
const num = Number(value);
if (isNaN(num)) throw new Error(`Параметр ${key} не является числом`);
result[key] = num;
} else if (rule.type === 'string') {
result[key] = String(value).replace(/[^a-zA-Z0-9_-]/g, '');
}
}
return result;
}
router.on('/post/:postId/:commentId', (params) => {
try {
const safeParams = sanitizeParams(params, {
postId: { type: 'number' },
commentId: { type: 'number' }
});
console.log(safeParams);
} catch (e) {
router.navigate('/error');
}
});
Такой подход позволяет централизованно управлять правилами санитизации и облегчает поддержку приложения.
Navigo также поддерживает query-параметры. Их можно получить через
метод getQueryString и вручную обработать:
const query = router.lastRouteResolved().query;
const page = Number(query.page) || 1;
const filter = (query.filter || '').replace(/[^a-zA-Z0-9]/g, '');
Рекомендуется всегда приводить query-параметры к ожидаемому типу и удалять запрещённые символы.
Соблюдение этих правил делает работу с Navigo более безопасной и предсказуемой, снижая вероятность ошибок и уязвимостей при работе с динамическими маршрутами и параметрами.