← Назад к вопросам

Что такое CSRF токен?

1.8 Middle🔥 111 комментариев
#Безопасность#Сетевые протоколы и API

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое CSRF-токен?

CSRF-токен (Cross-Site Request Forgery Token) — это уникальный, секретный и непредсказуемый токен, который генерируется сервером и передаётся клиенту для защиты от атак типа «межсайтовая подделка запроса» (CSRF). Этот токен подтверждает, что запрос, отправленный клиентом, был инициирован легитимным пользователем с авторизованной сессии, а не злоумышленником с другого сайта.

Как работает CSRF-токен?

Механизм защиты с использованием CSRF-токена включает следующие шаги:

  1. Генерация токена — сервер создаёт криптографически случайный токен (обычно 32+ байт) и привязывает его к сессии пользователя. Пример генерации в Go:
import (
    "crypto/rand"
    "encoding/base64"
)

func generateCSRFToken() (string, error) {
    token := make([]byte, 32)
    if _, err := rand.Read(token); err != nil {
        return "", err
    }
    return base64.URLEncoding.EncodeToString(token), nil
}
  1. Передача токена клиенту — токен внедряется в HTML-формы как скрытое поле или добавляется в заголовки AJAX-запросов. Пример формы:
<form method="POST" action="/transfer">
    <input type="hidden" name="csrf_token" value="abc123...">
    <input type="text" name="amount">
    <button type="submit">Перевести</button>
</form>
  1. Верификация токена — при получении POST/PUT/DELETE запроса сервер сравнивает токен из запроса с токеном в сессии пользователя:
func verifyCSRFToken(sessionToken, requestToken string) bool {
    return subtle.ConstantTimeCompare(
        []byte(sessionToken),
        []byte(requestToken),
    ) == 1
}
  1. Отказ в обработке — если токены не совпадают или отсутствуют, запрос отклоняется с ошибкой 403 Forbidden.

Почему CSRF-токены эффективны?

  • Непредсказуемость — злоумышленник не может угадать токен для конкретной сессии
  • Привязка к сессии — каждый пользователь получает уникальный токен
  • Требование присутствия — атакующий сайт не может прочитать токен из-за политики Same-Origin Policy
  • Простота реализации — минимальные накладные расходы

Реализация в Go-фреймворках

Большинство современных фреймворков предоставляют встроенную защиту:

  • Gin — через middleware gin.csrf:
import "github.com/gin-gonic/gin"
import "github.com/utrack/gin-csrf"

func main() {
    r := gin.Default()
    r.Use(csrf.Middleware(csrf.Options{
        Secret: "secret-key",
        ErrorFunc: func(c *gin.Context) {
            c.String(403, "CSRF token mismatch")
            c.Abort()
        },
    }))
}
  • Gorilla/csrf — популярная standalone библиотека:
import "github.com/gorilla/csrf"

func main() {
    CSRF := csrf.Protect(
        []byte("32-byte-long-auth-key"),
        csrf.Secure(false), // true для HTTPS
    )
    http.ListenAndServe(":8000", CSRF(mux))
}

Лучшие практики использования

  • Токен должен быть уникальным для каждой сессии — перегенерация при аутентификации
  • Использовать Constant-Time сравнение — для предотвращения timing-атак
  • Защищать все изменяющие состояние операции — POST, PUT, DELETE, PATCH
  • Не использовать GET для изменяющих операций — даже с токеном
  • Реализовать токен как для форм, так и для AJAX — через заголовки X-CSRF-Token
  • Учитывать особенности SPA — передача токена через cookies с флагом SameSite=Strict

Альтернативы и дополнения

  • SameSite cookies — современные браузеры поддерживают атрибут SameSite, ограничивающий отправку cookies
  • Двойная отправка cookies — токен хранится в cookie и сравнивается с значением в теле запроса
  • Custom заголовки — требование наличия специальных заголовков для AJAX-запросов

CSRF-токен остается фундаментальным механизмом защиты веб-приложений, несмотря на появление дополнительных мер. В сочетании с другими практиками безопасности (HTTPS, валидация ввода, принцип минимальных привилегий) он создает надежный барьер против межсайтовых атак, сохраняя при этом удобство использования для легитимных пользователей.