Санитизация параметров

Navigo — это легковесный роутер для JavaScript, позволяющий управлять маршрутами в одностраничных приложениях (SPA). Одним из ключевых аспектов безопасного и предсказуемого поведения роутера является корректная обработка параметров маршрутов. Санитизация параметров помогает предотвратить ошибки при передаче данных в URL, а также снижает риски XSS-атак и других уязвимостей.


Форматы параметров маршрута

В Navigo параметры маршрута задаются с помощью двоеточия :. Например:

router.on('/user/:id', (params) => {
  console.log(params.id);
});

Здесь :id — динамический параметр. Когда пользователь переходит по URL /user/42, объект params будет содержать { id: "42" }.

Важно: По умолчанию Navigo передает параметры как строки, без какой-либо фильтрации или преобразования. Поэтому крайне важно санитизировать входящие значения перед использованием их в приложении.


Основные методы санитизации

  1. Проверка типов и форматирование

Для числовых идентификаторов следует использовать преобразование в число и проверку:

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');
}
  1. Экранирование HTML

Если параметр будет вставляться в DOM, необходимо экранировать специальные символы:

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

const safeUsername = escapeHTML(params.username);
document.querySelector('#username').textContent = safeUsername;
  1. Использование регулярных выражений в маршрутах

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');
  }
});

Такой подход позволяет централизованно управлять правилами санитизации и облегчает поддержку приложения.


Санитизация query-параметров

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-параметры к ожидаемому типу и удалять запрещённые символы.


Практические рекомендации

  • Всегда проверять параметры маршрутов, особенно если они используются для запросов к серверу.
  • Применять регулярные выражения в маршрутах для базовой фильтрации.
  • Экранировать значения перед вставкой в DOM.
  • Использовать централизованные функции санитизации для унификации и поддержки.
  • Ограничивать длину строковых параметров, чтобы предотвратить переполнение и потенциальные уязвимости.

Соблюдение этих правил делает работу с Navigo более безопасной и предсказуемой, снижая вероятность ошибок и уязвимостей при работе с динамическими маршрутами и параметрами.