Поиск по сайту
Ctrl + K
Вопросы по Веб-разработке

Как реализовать защиту от CSRF в веб-приложении?

Защита от подделки межсайтовых запросов (CSRF, Cross-Site Request Forgery) является важным аспектом безопасности веб-приложений. CSRF-атака происходит, когда злоумышленник заставляет пользователя выполнить нежелательные действия на веб-сайте, где он аутентифицирован.

Основные принципы защиты от CSRF

  • Использование уникальных токенов для форм: Каждый раз, когда вы создаете форму отправки данных, включайте уникальный токен. Этот токен должен быть проверен на сервере перед выполнением запроса.
  • Проверка заголовка Origin и Referrer: Сервер должен проверять заголовки Origin и Referrer, чтобы убедиться, что запросы исходят от вашего сайта.
  • Частота изменения токенов: Токены должны быть уникальными для каждого пользователя и, при возможности, должны изменяться с каждой сессией.
  • Примеры реализации

    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 является критически важной для безопасности вашего веб-приложения. Внедрение токенов и проверка заголовков – это основные методы, которые помогут защитить ваше приложение от подобных атак. Надеюсь, этот материал был полезен для вас!

    Содержание:
    Редактировать