CSRF (Cross-Site Request Forgery) — это тип атаки, при котором злоумышленник заставляет браузер аутентифицированного пользователя выполнять нежелательные действия на сайте, где пользователь имеет права доступа. На уровне маршрутизации в JavaScript это особенно важно, так как маршрутизаторы управляют обработкой запросов и могут выступать точкой контроля доступа к различным ресурсам.
При использовании Universal Router критично учитывать, что маршруты не только направляют запросы на нужные обработчики, но и могут выступать в роли фильтров безопасности. Неправильная конфигурация маршрутов или отсутствие проверки токенов CSRF может позволить атакующему выполнить запрос от имени пользователя без его ведома.
Universal Router предоставляет абстрактный способ обработки маршрутов на стороне клиента и сервера. Основная стратегия защиты от CSRF заключается в проверке токена в каждом изменяющем состояние запросе (POST, PUT, DELETE). Реализация в контексте Universal Router включает несколько ключевых компонентов:
На сервере создаётся уникальный CSRF токен для каждой сессии пользователя. Обычно это случайная строка достаточной длины, например, 128 бит. Токен хранится в сессии или в HTTP-only cookie, а клиент получает его через безопасный канал (например, через HTML мета-тег или через JSON-ответ API).
// Node.js пример генерации токена
const crypto = require('crypto');
function generateCsrfToken() {
return crypto.randomBytes(16).toString('hex');
}
Важно, чтобы токен был одноразовым или обновлялся регулярно, чтобы снизить риск использования украденного токена.
На клиентской стороне Universal Router может извлекать токен из cookies или мета-тега и включать его в заголовки всех изменяющих состояние запросов.
function getCsrfToken() {
return document.querySelector('meta[name="csrf-token"]').getAttribute('content');
}
async function postData(url, data) {
const token = getCsrfToken();
return fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': token
},
body: JSON.stringify(data)
});
}
Здесь ключевой момент: каждый POST-запрос снабжается токеном, что предотвращает его подделку злоумышленником.
На серверной стороне Universal Router может использоваться для обработки как клиентских маршрутов, так и API-запросов. Валидация CSRF токена должна выполняться на этапе разрешения маршрута, до выполнения логики изменения данных.
const routes = [
{
path: '/update-profile',
action: async (context) => {
const { request } = context;
const token = request.headers['x-csrf-token'];
if (!validateCsrfToken(token, request.session)) {
throw new Error('Invalid CSRF token');
}
return updateUserProfile(request.body);
}
}
];
Особенности реализации:
validateCsrfToken сравнивает токен из запроса с
токеном, хранящимся в сессии или cookie.Хотя CSRF — серверная угроза, маршрутизация на клиенте тоже влияет на защиту. Universal Router может использовать посредники (middlewares) для проверки состояния перед переходом на маршрут:
function csrfMiddleware(context, next) {
if (context.request.method !== 'GET') {
const token = context.request.headers['x-csrf-token'];
if (!validateCsrfToken(token, context.session)) {
throw new Error('CSRF token missing or invalid');
}
}
return next();
}
const router = new UniversalRouter(routes, { context: { session } });
router.resolve({ path: '/update-profile', request })
.then(result => console.log(result))
.catch(err => console.error(err));
Такой подход позволяет встроить централизованную проверку CSRF в обработку маршрутов, обеспечивая одинаковую защиту для всех изменений состояния приложения.
SameSite=Strict или Lax снижает риск
автоматического отправления cookie при сторонних запросах.Правильная интеграция CSRF защиты в Universal Router требует согласованной работы сервера и клиента, строгого контроля токенов и правильной обработки маршрутов. Это критически важно для предотвращения подделки запросов и обеспечения безопасного взаимодействия пользователя с приложением.