CSRF (Cross-Site Request Forgery) — это тип веб-уязвимости, при котором злоумышленник заставляет браузер пользователя выполнить нежелательный запрос к доверенному сайту, на котором пользователь уже аутентифицирован. В контексте Slim.js, как и при работе с любыми веб-приложениями на JavaScript, защита от CSRF требует комбинации серверных и клиентских механизмов.
CSRF-атака обычно использует доверие сайта к браузеру пользователя. Если пользователь вошёл в систему и имеет активную сессию (cookie), злоумышленник может заставить его браузер выполнить действия от его имени, например:
Ключевой момент: браузер автоматически прикрепляет cookie сессии к каждому запросу, поэтому достаточно простого GET или POST запроса для успешной атаки.
CSRF-токены Наиболее распространенный способ защиты. Сервер генерирует уникальный токен для каждой сессии или запроса, который клиент должен включить в форму или заголовок запроса.
Генерация токена: Токен создаётся на сервере и хранится в сессии пользователя.
// Node.js пример генерации
const crypto = require('crypto');
function generateCSRFToken(session) {
const token = crypto.randomBytes(32).toString('hex');
session.csrfToken = token;
return token;
}Включение в форму: В Slim.js компоненте форма может содержать скрытое поле с токеном:
<form method="POST" action="/update-profile">
<input type="hidden" name="csrfToken" value="{{csrfToken}}">
<input type="text" name="username">
<button type="submit">Сохранить</button>
</form>Проверка токена: На сервере при обработке запроса токен сравнивается с тем, что хранится в сессии:
function verifyCSRFToken(session, token) {
return token && session.csrfToken && token === session.csrfToken;
}Защита через заголовки Для AJAX-запросов часто
используют заголовок X-CSRF-Token. Slim.js позволяет легко
интегрировать такой подход:
fetch('/api/update', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken
},
body: JSON.stringify({username: 'newName'})
});SameSite для cookie Установка атрибута
SameSite для cookies ограничивает отправку сессионного
cookie только теми запросами, которые инициированы с того же сайта:
res.cookie('sessionId', sessionId, { httpOnly: true, sameSite: 'Strict' });
Strict предотвращает отправку cookie в любых сторонних
запросах.Lax позволяет отправку при навигации, но блокирует
автоматические POST-запросы.Двойная проверка токена (Double Submit Cookie) Токен одновременно хранится в cookie и передается в теле запроса. Сервер проверяет совпадение значений. Этот метод позволяет снизить нагрузку на серверную сессию.
Slim.js ориентирован на работу с компонентами и реактивными данными. CSRF-токен удобно хранить в состоянии компонента и автоматически внедрять его в формы и запросы:
import { component, html } from 'slim-js';
component('update-form', class extends HTMLElement {
onBeforeMount() {
this.state = { csrfToken: window.csrfToken };
}
onSubmit(e) {
e.preventDefault();
fetch('/api/update', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': this.state.csrfToken
},
body: JSON.stringify({ username: this.querySelector('#username').value })
});
}
render() {
return html`
<form @submit=${this.onSubmit.bind(this)}>
<input id="username" type="text" name="username">
<button type="submit">Обновить</button>
</form>
`;
}
});
Ключевой аспект: токен передается только через безопасный канал, и компоненты автоматически используют его при каждом запросе.
SameSite и
HttpOnly cookie для максимальной защиты.В SPA на Slim.js все взаимодействия обычно идут через
fetch или XHR. Здесь критично:
Для традиционных HTML-форм токен внедряется в скрытые поля, и сервер проверяет их при каждом POST-запросе.
Систематическое внедрение этих методов обеспечивает надежную защиту от CSRF-атак в приложениях на Slim.js, сочетая безопасность с удобством работы компонентов и реактивного состояния.