Cross-Site Request Forgery (CSRF) представляет собой угрозу безопасности, при которой злоумышленник заставляет пользователя выполнить нежелательное действие на веб-сайте, на котором он авторизован. Эта атака возможна, если сервер не проверяет, что запрос был отправлен с допустимого источника. В приложениях, построенных с использованием фреймворка Marko, CSRF-защита имеет особое значение, так как веб-приложения часто требуют аутентификацию пользователей и обрабатывают различные формы.
CSRF-атака использует доверие пользователя к веб-приложению. Примером может быть ситуация, когда пользователь авторизован на веб-сайте, а затем посещает другую страницу, на которой находится скрипт, отправляющий запросы на исходный сайт. Если на сервере нет механизмов защиты от таких действий, запрос может быть выполнен от имени пользователя, что может привести к нежелательным последствиям: удалению данных, переводу средств или изменению личной информации.
Для предотвращения CSRF-атак важно удостовериться, что все запросы, которые могут повлиять на данные (например, POST, PUT, DELETE), защищены от подделки. Рассмотрим несколько методов защиты:
Использование токенов CSRF
Один из наиболее распространенных методов защиты от CSRF-атак заключается в применении токенов. Токен CSRF — это случайная строка, которая генерируется сервером и передается клиенту. При отправке запроса клиент должен включить этот токен, и сервер проверяет его соответствие. Если токен отсутствует или неверен, запрос отклоняется.
Проверка источника запросов
Еще одним способом защиты является проверка заголовка
Origin или Referer. Этот заголовок указывает,
с какого домена был отправлен запрос. Если запрос пришел с другого
домена, его можно отклонить, если только не разрешено выполнение
запросов из внешних источников.
Использование куки с флагом HttpOnly и SameSite
Для обеспечения безопасности куки, которые используются для хранения
информации о сессии, важно установить флаг SameSite. Это
ограничивает отправку куки с кросс-доменными запросами, предотвращая
возможность их использования в CSRF-атаках. Дополнительно стоит
установить флаг HttpOnly, чтобы куки не могли быть доступны
через JavaScript.
Генерация и валидация токенов CSRF
Для реализации CSRF-защиты на серверной стороне можно использовать
пакет csurf, который интегрируется с Express и другими
фреймворками, поддерживающими middleware.
Установка:
npm install csurf
Подключение и настройка middleware в Express:
const express = require('express');
const csurf = require('csurf');
const bodyParser = require('body-parser');
const app = express();
// Настройка body-parser
app.use(bodyParser.urlencoded({ extended: false }));
// Настройка csurf
const csrfProtection = csurf();
app.use(csrfProtection);
app.get('/form', (req, res) => {
res.marko({
csrfToken: req.csrfToken() // Передаем токен в шаблон Marko
});
});
В шаблоне Marko необходимо вставить токен CSRF в скрытое поле формы:
<form method="POST" action="/submit">
<input type="hidden" name="_csrf" value="${csrfToken}">
<!-- Остальные поля формы -->
<button type="submit">Отправить</button>
</form>
При отправке формы сервер проверит токен, и если он не совпадает с тем, что был сгенерирован на сервере, запрос будет отклонен.
Проверка заголовков Origin и Referer
Важным элементом защиты является проверка, откуда был отправлен
запрос. Это можно сделать с помощью middleware, который будет проверять
заголовки Origin или Referer.
Пример middleware для проверки Origin:
app.use((req, res, next) => {
const allowedOrigin = 'https://yourtrustedsite.com';
const origin = req.get('Origin') || req.get('Referer');
if (origin && !origin.startsWith(allowedOrigin)) {
return res.status(403).send('Forbidden');
}
next();
});
Такой подход предотвратит обработку запросов, которые не пришли с ожидаемого домена.
Настройка SameSite для cookies
Чтобы предотвратить отправку куки с кросс-доменными запросами,
необходимо установить для сессионных куки флаг SameSite. В
Express можно использовать модуль cookie-session для
настройки этого флага:
const cookieSession = require('cookie-session');
app.use(cookieSession({
name: 'session',
keys: ['your-secret-key'],
cookie: {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'Strict' // Включение защиты от CSRF через SameSite
}
}));
Этот флаг гарантирует, что куки не будут отправляться в запросах, сделанных с других сайтов.
CSRF-защита является важной частью безопасности веб-приложений, и фреймворк Marko предоставляет все необходимые возможности для её реализации. Использование токенов CSRF, проверка источников запросов и правильная настройка куки — эти меры помогают защитить веб-приложения от одной из самых распространенных угроз безопасности.