CSRF (Cross-Site Request Forgery) — это тип уязвимости, при котором злоумышленник вынуждает пользователя выполнить нежелательное действие на веб-приложении, в котором тот аутентифицирован. В отличие от XSS, CSRF использует доверие приложения к пользователю, а не доверие пользователя к приложению.
Принцип атаки: злоумышленник создаёт запрос, который выглядит легитимным для сервера, и заставляет пользователя отправить его. Например, это может быть форма на стороннем сайте, которая автоматически отправляет POST-запрос на ваш сервер от имени аутентифицированного пользователя.
Ключевая опасность заключается в том, что сервер доверяет cookies или токенам сессии, автоматически прикрепляемым браузером к запросам. Если не применяются меры защиты, злоумышленник может изменить данные пользователя, провести финансовые транзакции или изменить настройки аккаунта.
CSRF-токен — уникальное значение, генерируемое сервером для каждой сессии или формы. Оно включается в HTML-форму и проверяется сервером при получении запроса.
Принцип работы:
Особенности реализации в SPA:
fetch или
axios токен включается в заголовок, например
X-CSRF-Token.// Пример отправки запроса с CSRF-токеном
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
fetch('/api/update', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken
},
body: JSON.stringify({ data: 'новое значение' })
});
Сервер может проверять заголовки Origin и
Referer для POST-запросов.
Origin сообщает домен, с которого пришёл запрос.Referer указывает полный URL страницы, откуда был
инициирован запрос.Пример проверки на сервере:
const validOrigins = ['https://example.com'];
if (!validOrigins.includes(req.headers.origin)) {
res.status(403).send('Forbidden: invalid origin');
}
Эта защита работает только для современных браузеров, поддерживающих заголовки, и подходит для запросов с CORS.
Флаги SameSite и HttpOnly
помогают ограничить риск CSRF:
SameSite=Strict или Lax предотвращает
отправку cookies при межсайтовых запросах.HttpOnly предотвращает доступ к cookie через
JavaScript, но не защищает от CSRF напрямую — больше от XSS.Пример настройки cookie:
res.cookie('session', sessionId, { httpOnly: true, sameSite: 'Strict' });
Запросы, которые изменяют состояние на сервере, должны использовать
методы POST, PUT, DELETE.
GET-запросы должны оставаться идемпотентными и не изменять данные. Это
ограничивает возможности CSRF-атак, так как браузеры автоматически не
отправляют кросс-доменные POST-запросы без пользовательского
взаимодействия.
В приложениях Riot.js рекомендуется:
fetch или кастомный
store-метод.// Глобальная функция для POST-запросов с токеном
export function postWithCSRF(url, data) {
const token = window.csrfToken;
return fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': token
},
body: JSON.stringify(data)
});
}
Использование этих практик снижает риск CSRF-атак до минимума и обеспечивает безопасное взаимодействие компонентов Riot.js с сервером.
SameSite для
cookies.Эти меры позволяют создавать безопасные, масштабируемые приложения на Riot.js, минимизируя уязвимость к CSRF.