TGViewer
Go Update Go Update @go_update · 3.23K subscribers
Post #92 2.91K
🛡️ Go 1.25: встроенная защита от CSRF в net/http 🛡️

Тем временем разработчики стандартной библиотеки продолжают упрощать нам жизнь. Практически всё кто связаны с вебразработкой слышали про атаку CSRF. Суть в том, что используя форму (и не только) злонамеренный сайт может заставить ваш браузер выполнить, например, перевод денег из банка на другой счёт, если у банка нет защиты от CSRF, а у вас в этот момент действующая кука от ЛК банка.

Я не буду касаться описания принципов работы "same site" и "same origin", так как про это написано уже масса статей, а коснусь лишь основных механизмов защиты от CSRF:

• Вместе с кукой присылать скрытый <input> в котором присылать дубль токена, который идет в самой куке. Если при запросе то, что в форме и то, что в куке не совпало — запрос отклоняется. Недостаток в том, что токен надо привязывать к пользователю и добавлять в каждую форму.
• Проверять через заголовок Origin что инициатор запроса был сам исходный сайт, а не сторонний. Тоже обладает рядом минусов (может быть null при кривых плагинах), и требует довольно сложной настройки для правильной поддержки cross-origin запросов.
• SameSite куки и "Non-simple requests" которые защищают от вариантов атаки HTTP -> HTTPS но в общем случае бесполезны.

На данный момент для защиты от CSRF в нашей экосистеме есть две либы: csrf и nosurf. Обе работают через дубль токена (т.е. требуют донастройки фронта) и обе почти не поддерживаются разработчиками.

Поэтому Go 1.25 в пакет net/http добавили готовую «прослойку» для защиты от CSRF, построенную на механизме Fetch Metadata который присутствует во всех современных браузерах с 2023го года.

Заголовок с сайта банка при запросе через fetch в таком случае будет выглядеть так:

GET /money/foo.json
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty


В то время как заголовок от зловредного сайта при «прямой» подгрузке будет выглядеть вот так


GET /money/cool.jpg
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: image


Сам proposal добавляет лишь один тип CrossOriginProtection, который предназначен для оборачивания ваших обработчиков.

Как это работает:

• Браузер добавляет Sec-Fetch-Site (same-origin / same-site / cross-site / none). Хендлер смотрит это заголовок, и если это не same-origin или none а метод это POST/PUT/PATCH/DELETE то запрос режется. Тоже самое если нет Sec-Fetch-Site: тогда смотрим Origin и сравниваем с Host и опять же, в случае несовпадения, режем POST/PUT/PATCH/DELETE запросы.
• В случае если дополнительно установлен список ориджинов через метод AddTrustedOrigin то полученный запрос сравнивается по заголовку Origin пока не будет найдет нужный, или запрос не будет отклонен.
• Запросы без Sec-Fetch-Site и без Origin пропускаются тк их явно не мог сделать браузер, защищать нечего.
• «Безопасные» методы GET/HEAD/OPTIONS всегда пропускаются (уповают на то, что вы не меняете состояние в этих методах и следуете разумным практикам)

Для более сложных случаев предусмотрены методы AddInsecureBypassPattern и функция SetDenyHandler которая явно разрешает запрос.
MDN Web Docs Cross-site request forgery (CSRF) - Security | MDN In a cross-site request forgery (CSRF) attack, an attacker tricks the user or the browser into making an HTTP request to the target site from a malicious site. The request includes the user's credentials and causes the server to carry out some harmful action…
  • 👍 16
  • ❤ 4
More from @go_update
  1. Aug 22, 2026Об изоляции LLM Да, это ещё один пост про работу с Codex/Claude/GLM/Qwen/DeepSeek и прочая…
  2. Aug 11, 2026И вот эти два минуса выглядят нерешенными (на данный момент времени). Можно ли их решить в…
  3. Aug 11, 2026🎂 Вечерний пост о том, что сегодня мне исполнилось 34. Прошёл еще один год, а значит врем…
  4. Jul 13, 2026📝 testing: allow examples with any signature Небольшое «Quality of Life» предложение. Сут…
  5. May 14, 2026📝 net/http/httptest: synctest support Я уже писал про пакет synctest и его возможности. Э…
  6. May 13, 2026Я редко пишу сюда о вещах которые не относятся к Go, но тут у меня появилась хорошая стать…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →