CSRF (Cross-Site Request Forgery) — это тип веб-уязвимости, при которой злоумышленник вынуждает пользователя выполнить нежелательное действие на доверенном сайте, где у него есть авторизованный сеанс. В отличие от XSS, CSRF использует доверие сервера к браузеру пользователя, а не доверие пользователя к сайту.
CSRF атакующий использует существующую аутентификацию пользователя. Основные шаги атаки:
Пример типичного сценария: форма для изменения пароля или перевода средств, которая может быть вызвана с другого сайта через POST-запрос.
Токены CSRF являются основным способом защиты. Они представляют собой уникальные секретные значения, генерируемые сервером и передаваемые клиенту для каждой сессии или формы.
Принцип работы токенов:
Если токен передаётся через метатег в HTML:
<meta name="csrf-token" content="UNIQUE_CSRF_TOKEN">
В Vue.js его можно получить через Jav * aScript:
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
При использовании axios токен можно передавать через
заголовок X-CSRF-Token:
import axios from 'axios';
axios.defaults.headers.common['X-CSRF-Token'] = csrfToken;
axios.post('/api/update-profile', {
name: 'Иван'
}).then(response => {
console.log('Данные обновлены', response.data);
}).catch(error => {
console.error('Ошибка обновления', error);
});
Альтернатива — добавление токена в тело POST-запроса, если сервер ожидает его в параметрах формы:
axios.post('/api/update-profile', {
name: 'Иван',
_csrf: csrfToken
});
Для проектов на Vue 3 с Composition API и axios удобно
создать плагин, который автоматически прикрепляет токен ко всем
запросам:
import { createApp } from 'vue';
import axios from 'axios';
import App from './App.vue';
const app = createApp(App);
axios.interceptors.request.use(config => {
const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
if (token) {
config.headers['X-CSRF-Token'] = token;
}
return config;
});
app.config.globalProperties.$http = axios;
app.mount('#app');
Это позволяет не вставлять токен вручную в каждый компонент.
SameSite cookie, чтобы ограничить отправку
cookie только с доверенного домена.JWT
аутентификация, рекомендуется использовать заголовки авторизации вместо
cookie, что снижает риск CSRF, но токены остаются актуальным
инструментом защиты для форм и сессий.Vue.js как фронтенд-фреймворк активно использует AJAX-запросы, поэтому CSRF токены часто передаются через заголовки. Важно:
axios interceptors или Vue plugins), чтобы исключить
ошибки при ручной вставке токена.На Node.js с использованием Express и middleware csurf
проверка выглядит так:
import express from 'express';
import csurf from 'csurf';
import cookieParser from 'cookie-parser';
const app = express();
app.use(cookieParser());
app.use(csurf({ cookie: true }));
app.get('/form', (req, res) => {
res.send(`<form method="POST" action="/update">
<input type="hidden" name="_csrf" value="${req.csrfToken()}">
<input type="text" name="name">
<button type="submit">Отправить</button>
</form>`);
});
app.post('/update', (req, res) => {
res.send('Данные обновлены');
});
Совместное использование CSRF токенов и корректной настройки заголовков безопасности позволяет снизить риск атак практически до нуля, даже при работе с современными SPA на Vue.js.