Go CSRF / XSRF Токен: Цель, защита форм и срок действия токена по умолчанию в стандартном пакете

7 min

language: ja bn en es hi pt ru zh-cn zh-tw

Здравствуйте, я бездарь.
У меня есть онлайн-хранилище, которое я сделал и использую лично:
GitHub - haturatu/puremania: No security, very fast, web UI self-hosted online storage
И если есть необходимость добавить аутентификацию перед ним, я сделал прокси-сервер аутентификации.
GitHub - haturatu/auth-proxy: An authentication proxy server and frontend for a website without built-in authentication. JavaScript is supported, but it can also work without JS if using PHP-FPM. The backend is written in Go.
На самом деле, это почти полностью благодаря Gemini...
Он проксирует только то, что проходит аутентификацию.
Администратор также может выдавать токены Bearer для конечных точек API и использовать их для прохождения запросов. Однако, в этом случае есть конечные точки API, к которым необходимо получить доступ из сессии фронтенда, поэтому на самом деле можно использовать как куки, так и токены Bearer.
Если вы хотите защитить только конечные точки API, вы можете изолировать фронтенд, такой как веб-вход, в частной сети и публиковать только конечные точки API. Тогда создание пользователей будет происходить из частной сети, и с использованием этих пользователей можно будет выдавать токены API и использовать API-прокси. (Пожалуйста, не говорите, что можно просто использовать OSS типа API Gateway)
На самом деле, в этом случае становится возможным двойной брутфорс с использованием куки и токенов, но, ну...

Итак, речь пойдет о безопасности форм для фронтенда веб-сайта при входе в систему.
Если сделать загрузку JS обязательной, большинство проблем можно решить, но разве не скучно полагаться только на JS? Поэтому я решил повысить безопасность форм другими способами, помимо JS.

CSRF / XSRF Токен

Это будет основной темой, но что это вообще такое?

Проще говоря, это механизм, который проверяет, был ли запрос сгенерирован с моего сервера и выдан клиенту, и если токен действителен в течение срока действия, то запрос разрешается.
Например,

<input type="hidden" name="xsrf_token" value="BeftikzaR8Oe6npnqXYC7WtBhuo:1760376550660">

Такой токен встраивается в HTML на стороне фронтенда. Это value подписано секретным ключом сервера. Таким образом, сервер знает, что он был выдан с моего сервера!
1760376550660 — это просто последовательность символов в формате UNIX-времени, но для чего она нужна в текущем времени?
xsrftoken package - golang.org/x/net/xsrftoken - Go Packages

func ValidFor(token, key, userID, actionID string, timeout time.Duration) bool

Используется для установки вышеуказанного срока действия.

На самом деле, с добавлением пакета time это выглядит так:

if !xsrftoken.ValidFor(clientToken, string(xsrfSecret), sessionID, r.URL.Path, 15*time.Minute) {

По умолчанию, если этот аргумент не указан, срок действия составляет 24 часа, что довольно свободно. Однако, я думаю, что это соответствует первоначальной форме предоставления XSRF Token, когда требуется только проверка того, что токен был выдан сервером.

В чем разница между CSRF и XSRF, черт возьми!

На самом деле, кажется, особой разницы нет.
Цель — предотвращение межсайтовых атак.

В случае CSRF
GitHub - gorilla/csrf: Package gorilla/csrf provides Cross Site Request Forgery (CSRF) prevention middleware for Go web applications & services 🔒
Я наткнулся на эту библиотеку.
Демо уязвимости CSRF в gorilla/csrf

Один из способов улучшить реализацию gorilla/csrf — заменить случайное значение, используемое в форме, на зашифрованный токен, связанный с ID пользователя. Это предотвращает подмену атакующим своего CSRF-токена и значения куки на те, которые принадлежат жертве. Потому что CSRF-токен атакующего соответствует другому ID. На самом деле, этот метод реализован в библиотеке, которая использует x/net/xsrftokenHMAC для аутентификации ID пользователя, необязательного действия формы и срока действия.

Поэтому я подумал, что это должно быть в стандартной библиотеке,
xsrftoken/xsrf.go
и был удивлен, увидев исходный код: всего 100 строк, включая комментарии! Немного беспокоит, что SHA1 все еще используется, но, возможно, это изменится в будущем.
Итак, если стандартная библиотека настолько проста, то для поставленной цели этого достаточно, а если нужно проверять SameSite, то, вероятно, следует использовать gorilla/csrf.

Особенности стандартной библиотеки

Как я уже упоминал, срок действия токена по умолчанию составляет 24H.
В реальной эксплуатации такой срок действия токена может быть использован злоумышленниками, поэтому, возможно, стоит сделать его короче. Предполагается, что этот токен используется для отправки запросов до заполнения формы. Если срок действия 24 часа и нет других мер безопасности, то один и тот же токен может быть использован для многократных запросов, что позволяет проводить брутфорс, отправляя запросы к форме с одним и тем же токеном через бесконечный curl.

Related Posts