Как реализовать защиту от CSRF в веб-приложении?
Защита от подделки межсайтовых запросов (CSRF, Cross-Site Request Forgery) является важным аспектом безопасности веб-приложений. CSRF-атака происходит, когда злоумышленник заставляет пользователя выполнить нежелательные действия на веб-сайте, где он аутентифицирован.
Основные принципы защиты от CSRF
Примеры реализации
1. Генерация токена на стороне сервера
Допустим, у вас есть сервер на Node.js с использованием Express.
const express = require('express');
const crypto = require('crypto');
const session = require('express-session');
const app = express();
app.use(session({ secret: 'your-secret-key', resave: false, saveUninitialized: true }));
app.use(express.urlencoded({ extended: true }));
function generateCSRFToken() {
return crypto.randomBytes(16).toString('hex');
}
app.get('/form', (req, res) => {
const token = generateCSRFToken();
req.session.csrfToken = token; // сохраняем токен в сессии
res.send(`
<form method="POST" action="/submit">
<input type="hidden" name="_csrf" value="${token}">
<label for="data">Данные:</label>
<input type="text" id="data" name="data">
<button type="submit">Отправить</button>
</form>
`);
});
app.post('/submit', (req, res) => {
if (req.body._csrf !== req.session.csrfToken) {
return res.status(403).send('Forbidden: Invalid CSRF Token');
}
res.send('Данные успешно отправлены!');
});
app.listen(3000, () => {
console.log('Сервер запущен на http://localhost:3000');
});
В этом примере мы генерируем токен при каждой загрузке формы и сохраняем его в сессии. При отправке формы проверяем, совпадает ли полученный токен с тем, который хранится в сессии.
2. На стороне клиента
При использовании JavaScript (например, с React) для отправки формы, токен также можно включить через заголовок:
import React, { useState } from 'react';
import axios from 'axios';
const FormComponent = () => {
const [data, setData] = useState('');
const csrfToken = 'TOKEN_FROM_SERVER'; // Здесь должен быть ваш CSRF токен
const handleSubmit = async (e) => {
e.preventDefault();
try {
await axios.post('/submit', { data }, {
headers: {
'X-CSRF-Token': csrfToken
}
});
alert('Данные успешно отправлены!');
} catch (error) {
alert('Ошибка при отправке данных: ' + error.message);
}
};
return (
<form onSubmit={handleSubmit}>
<label>
Данные:
<input type="text" value={data} onChange={(e) => setData(e.target.value)} />
</label>
<button type="submit">Отправить</button>
</form>
);
};
export default FormComponent;
Заключение
Защита от CSRF является критически важной для безопасности вашего веб-приложения. Внедрение токенов и проверка заголовков – это основные методы, которые помогут защитить ваше приложение от подобных атак. Надеюсь, этот материал был полезен для вас!