> Что такое CSRF и как определить поддельный запрос (Go)

Уровень: junior · Роль: backend · Категория: Технические вопросы

Компании: VK

Стек: Go

> Пример ответа

Короткий ответ

CSRF (Cross-Site Request Forgery) - это атака, при которой злоумышленник заставляет браузер жертвы отправить поддельный запрос на сервер от её имени, используя её cookies или другие автоматические credentials. Поддельный запрос можно определить по отсутствию валидного CSRF-токена, который сервер генерирует и связывает с сессией пользователя. Также проверяют Origin и Referer заголовки, но токен - основной механизм защиты.

Подробное объяснение

CSRF возникает из-за того, что браузер автоматически добавляет cookies к запросам на домен, независимо от того, откуда инициирован запрос. Если пользователь авторизован на сайте, злоумышленник может разместить на своём сайте форму или скрипт, который отправит POST-запрос на целевой сайт. Сервер не может отличить легитимный запрос от поддельного, потому что cookies одинаковые.

Основной механизм защиты - синхронизированный CSRF-токен. Сервер при выдаче сессии генерирует случайное значение, сохраняет его в сессии (или в подписанной cookie) и отдаёт в HTML-форме или в заголовке. При каждом мутирующем запросе (POST, PUT, DELETE) клиент обязан передать этот токен. Сервер сравнивает переданный токен с сохранённым в сессии. Если они не совпадают - запрос отклоняется.

Дополнительные проверки:

  • заголовок Origin - сервер проверяет, что запрос пришёл с ожидаемого домена;
  • заголовок Referer - аналогично, но менее надёжен, так как может отсутствовать или быть подделан;
  • SameSite атрибут для cookies - ограничивает отправку cookies при cross-site запросах.

Важно понимать: CSRF-токен не защищает от XSS. Если злоумышленник может выполнить скрипт на странице, он прочитает токен и подставит его в запрос.

На практике

В Go для защиты от CSRF обычно используют middleware. Например, библиотека gorilla/csrf или justinas/nosurf. Middleware генерирует токен, внедряет его в шаблон и проверяет на входящих запросах.

На практике нужно:

  • генерировать токен для каждой сессии (или для каждой формы);
  • включать токен во все HTML-формы, которые отправляют мутирующие запросы;
  • для AJAX-запросов передавать токен в заголовке, например X-CSRF-Token;
  • проверять токен на сервере для всех POST, PUT, PATCH, DELETE запросов;
  • не использовать GET для изменения состояния - это снижает поверхность атаки.

Пример кода

GO
// middleware для проверки CSRF-токена
func CSRFMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet || r.Method == http.MethodHead || r.Method == http.MethodOptions {
next.ServeHTTP(w, r)
return
}
token := r.Header.Get("X-CSRF-Token")
if token == "" {
token = r.FormValue("csrf_token")
}
sessionToken := getSessionToken(r) // из сессии
if token == "" || !secureCompare(token, sessionToken) {
http.Error(w, "CSRF token mismatch", http.StatusForbidden)
return
}
next.ServeHTTP(w, r)
})
}
func secureCompare(a, b string) bool {
return subtle.ConstantTimeCompare([]byte(a), []byte(b)) == 1
}

Как отвечать на собеседовании

Начни с краткого определения: CSRF - это атака, при которой браузер жертвы отправляет поддельный запрос на сервер с её cookies. Затем объясни, почему это возможно: браузер автоматически прикрепляет cookies. После этого переходи к защите: главный механизм - CSRF-токен, который хранится в сессии и передаётся в каждом мутирующем запросе. Упомяни дополнительные меры: проверка Origin/Referer, атрибут SameSite. Если спросят про Go - скажи, что используешь middleware, например gorilla/csrf, и что токен нужно передавать в заголовке для AJAX.

Что проверяет интервьюер

Интервьюер проверяет:

  • понимание сути атаки и почему cookies не защищают;
  • знание основного механизма защиты - токена;
  • понимание разницы между CSRF и XSS;
  • знание дополнительных мер защиты и их ограничений;
  • умение реализовать защиту на практике, особенно в Go.

Типичные ошибки

  • путать CSRF с XSS - это разные атаки, хотя могут комбинироваться;
  • говорить, что защита - это проверка Referer - это слабый механизм, не основной;
  • не упоминать, что токен нужно проверять для всех мутирующих методов, а не только POST;
  • забывать, что токен не защищает от XSS;
  • предлагать использовать SameSite как единственную меру - это не всегда работает, особенно для старых браузеров;
  • не знать, как передать токен в AJAX-запросах.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью