При работе с Universal Router в JavaScript критически
важно учитывать, что маршруты могут принимать динамические параметры из
URL. Любой входной параметр, не прошедший валидацию, потенциально может
быть использован для атаки через инъекции. В контексте маршрутизации это
чаще всего проявляется в виде попыток изменения логики приложения через
специально сформированные URL-параметры.
Ключевой принцип: никогда не доверять данным, полученным из URL. Любой параметр должен проходить строгую проверку перед использованием.
Universal Router позволяет определять маршруты с
динамическими сегментами:
const routes = [
{
path: '/user/:id',
action: ({ params }) => {
return fetchUserById(params.id);
}
}
];
В этом примере params.id может содержать любой текст,
введённый пользователем. Если сразу передавать его в SQL-запрос или в
вызов функций без проверки, появляется уязвимость. Для защиты необходимо
использовать:
Проверку типов и формата Для числовых идентификаторов:
const userId = parseInt(params.id, 10);
if (isNaN(userId)) throw new Error('Неверный ID пользователя');Ограничение длины строки Для текстовых параметров стоит использовать ограничение по количеству символов:
if (params.name.length > 50) throw new Error('Имя слишком длинное');Белые списки допустимых значений Если маршрут принимает конкретные значения:
const allowedRoles = ['admin', 'editor', 'viewer'];
if (!allowedRoles.includes(params.role)) throw new Error('Недопустимая роль');В Universal Router часто динамические параметры
используются для рендеринга контента. В этом случае критически важно
предотвращать внедрение вредоносного HTML или скриптов:
function escapeHtml(str) {
return str
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
const routes = [
{
path: '/greet/:name',
action: ({ params }) => {
const safeName = escapeHtml(params.name);
return `<h1>Привет, ${safeName}</h1>`;
}
}
];
Это гарантирует, что даже если в params.name будет
вставлен скрипт, он не выполнится.
Маршруты могут выполнять асинхронные действия, например, запросы к API. Любые параметры, используемые в этих запросах, также должны проверяться и фильтроваться:
const routes = [
{
path: '/search/:query',
async action({ params }) {
const query = params.query.trim();
if (query.length > 100) throw new Error('Запрос слишком длинный');
// Пример использования безопасного параметра
return fetch(`/api/search?q=${encodeURIComponent(query)}`)
.then(res => res.json());
}
}
];
Использование encodeURIComponent предотвращает
вмешательство специальных символов в URL и защитит от атак типа
URL-инъекции.
Сложные вложенные маршруты повышают риск обхода валидации и внедрения
нежелательных действий. В Universal Router следует:
const routes = [
{
path: '/admin/:section',
children: [
{ path: 'users', action: () => loadUsers() },
{ path: 'settings', action: () => loadSettings() }
],
action: ({ params }) => {
const allowedSections = ['users', 'settings'];
if (!allowedSections.includes(params.section)) throw new Error('Недопустимый раздел');
}
}
];
Регулярные выражения в Universal Router позволяют строго
ограничивать, какие значения могут принимать параметры:
const routes = [
{
path: '/order/:orderId(\\d+)',
action: ({ params }) => getOrderById(params.orderId)
}
];
Здесь :orderId(\\d+) гарантирует, что параметр состоит
только из цифр. Любая попытка передать текст будет отклонена на этапе
маршрутизации.
Для повышения безопасности целесообразно вести журнал всех необычных или подозрительных запросов:
const routes = [
{
path: '/profile/:id',
action: ({ params }) => {
if (!/^\d+$/.test(params.id)) {
console.warn('Попытка передачи некорректного ID:', params.id);
}
return fetchProfile(params.id);
}
}
];
Такой подход помогает выявлять атаки на ранней стадии и обеспечивает аудит изменений, связанных с параметрами маршрутов.
encodeURIComponent).Эти меры обеспечивают надежную защиту приложений на основе
Universal Router от большинства видов инъекций,
предотвращая непреднамеренное выполнение кода или обход системы
маршрутизации.