秋来冬风的博客

Go1.25的新CSRF(跨站请求伪造)防御API | 构建更安全的互联网

目录

背景

Go1.25已经在2025年8月中旬发布。

此次更新中在标准库的net/http包中增加了防御CSRF(跨站请求伪造)的API。此API由Go语言密码包维护者Filippo Valsorda提出并添加进标准库,他是密码学家。

CSRF实现原理

CSRF原理是浏览器在向一个网站发送请求时,会自动同时发送这个网站保存的Cookie

意味着存在这么一种情况,用户点击了一个恶意链接,链接点后自动向特殊网站(例如用户的网上银行)发送请求,因为同时自动发送了这个网站保存的Cookie,服务器看到用户的Cookie,认为是用户本人的请求,导致一些恶意行为例如转走用户银行卡的钱被执行。

添加起因

Filippo Valsorda发现现在两个广泛使用防御CSRF攻击的Go库,似乎处于缺乏维护的状态(例如报告安全问题数周无回应)。

这些库中有些漏洞自2015年最初发布以来就一致存在,还存在要求开发者管理一个密钥来用签名token cookie,与其他专家讨论过这个问题,结论是签名和密钥是无效的。

新API

API签名

type CrossOriginProtection struct {}

func NewCrossOriginProtection() *CrossOriginProtection 

func (c *CrossOriginProtection) AddTrustedOrigin(origin string) error 

func (c *CrossOriginProtection) AddInsecureBypassPattern(pattern string) 

func (c *CrossOriginProtection) Check(req *http.Request) error 

func (c *CrossOriginProtection) Handler(h http.Handler) http.Handler

func (c *CrossOriginProtection) SetDenyHandler(h http.Handler)

API文档在 https://pkg.go.dev/net/http#CrossOriginProtection

API实现原理

过往防御CSRF的一些对策(CSRF token、SameSite cookies、Origin header ……),要么要求开发者付出额外努力(例如修改html表单)或存在各种各样的其他问题。

Go1.25添加的新API通过以下方式防御CSRF:

  1. 若请求方法为安全方法(GET、HEAD、OPTIONS),直接通过;
  2. 否则,检查 Sec-Fetch-Site:
    • 为 “same-origin”“none” → 通过;
    • 为其他非空值 → 检查是否允许绕过,是则通过,否则拦截;
  3. 若 Sec-Fetch-Site 为空,检查 Origin:
    • Origin 为空 → 通过;
    • Origin 的 Host 与请求 Host 一致 → 通过;
  4. 否则,检查是否允许绕过,是则通过,否则拦截。

关键点在于http Header的这些键值对:

  • Sec-Fetch-Site(自2023年以来,在所有主要浏览器中都已可用)
  • Origin(RFC 6454定义,跨源请求时浏览器自动发送)
  • Host(RFC 7230 (HTTP/1.1)标准的5.4节规定必须存在)

CSRF需要在用户的浏览器进行,所以如果伪造这些键值对,就违反了攻击的实现原理

例如,如果Sec-Fetch-Site是真实的,就不会通过检查,如果是伪造的的,就没有浏览器自动发送的用户Cookie

其他键值对也是如此。

过往防御的麻烦之处

CSRF token要修改html表单,要额外数据库存token。

SameSite cookies不能防御同一站点内不同子域名之间的攻击。

Origin Header存在和上面类似的问题,且在某些请求中不会被发。

新API的优势

  • 无需修改html表单等,不需要付出额外努力
  • 可以防御同一站点内不同子域名之间的攻击
  • 仅需一行代码(http.NewCrossOriginProtection().Handler(mux))即可启用防御

需要注意的

保持安全方法语义

对于GET等http安全方法,保持它们的语义,不要让这些方法用来进行敏感操作。

预防Cookie窃取

新API仅防御因浏览器自动发送Cookie的CSRF,如果用户的Cookie已经被窃取,它无能为力。

实践中应设置Cookie的HttpOnly和Secure,避免Cookie被窃取。

安全要求高的场景

对于金融,电商等等安全要求高的场景,可以使用CSRF token,避免太老旧的浏览器因为没有http Header需要的键值对,在被攻击时错误的通过检查。

Tags: