Go1.25通过Headers实现CSRF防护
跨站请求伪造(CSRF)是一种常见的 Web 安全攻击。当用户登录了银行网站后,又访问了一个恶意网站 fake-bank.com,该恶意网站可能显示如下表单:
<form action="https://bank.com/transfer" method="post"> <input type="hidden" name="amount" value="1000"> <input type="hidden" name="recipient" value="hacker-account"> <input type="submit" value="联系客服"> </form>
攻击者的目标是诱骗用户点击"联系客服"按钮,但实际上表单会被提交到银行网站。由于浏览器会自动携带用户已认证的 Cookie,银行网站会认为这是合法请求,从而执行转账操作。
传统的 CSRF 防护方案
传统防护方法需要服务器生成一个 CSRF Token,同时存储在 Cookie 和表单隐藏字段中。提交表单时,服务器验证两个 Token 是否匹配。这种方法有效的原因是恶意网站无法读取用户的 Cookie,因此无法构造正确的隐藏字段。
但这种方案存在明显缺点:
- 开发成本高:需要为每个表单添加 CSRF Token 字段
- 维护负担:通常依赖第三方库,可能存在维护问题
现代浏览器的 Headers 防护方案
现代浏览器新增了一些 Headers,可用于 CSRF 防护:
Sec-Fetch-Site Header
这个 Header 告诉我们请求是否跨域:
same-site或none:表示非跨域请求,无需 CSRF 防护- 其他值或缺失:需要结合 Origin Header 进一步验证
Origin Header
表示发起请求的网站来源。例如,如果在 https://fake-bank.com 点击链接,Origin Header 会设置为该域名。服务器可以通过验证 Origin 是否在白名单内来判断请求是否合法。
如果两个 Header 都不存在,通常认为是非浏览器客户端(如 API 测试工具),此时不强制 CSRF 防护。
优势:
- 实现简单,无需修改表单
- 无需维护 CSRF Token 和 Cookie
限制:
- 需要较新的浏览器(2023 年后发布的版本支持较好)
Go 1.25 中的 CrossOriginProtection
Go 1.25 在 net/http 包中新增了 CrossOriginProtection 类型,采用上述 Headers 方案提供 CSRF 防护。
基本用法
mux := http.NewServeMux()
mux.HandleFunc("/", homePageHandler)
mux.HandleFunc("POST /login", loginHandler)
// 更多路由...
// 创建 CSRF 防护
csrfProtection := http.NewCrossOriginProtection()
// 允许来自 client 子域的跨站请求
csrfProtection.AddTrustedOrigin("https://client.xx.com")
// 包装处理器
handler := csrfProtection.Handler(mux)
// 启动服务
http.ListenAndServe(":8080", handler)
此配置允许同域请求,以及来自 https://client.xx.com 的跨站请求。
测试验证
使用 curl 测试不同场景:
1. 同域请求(通过):
curl -v -X POST \ -H "sec-fetch-site:same-origin" \ localhost:8080/login
2. 信任的跨域来源(通过):
curl -v -X POST \ -H "sec-fetch-site:same-site" \ -H "origin:https://client.xx.com" \ localhost:8080/login
3. 未信任的跨域来源(拒绝):
curl -v -X POST \ -H "sec-fetch-site:same-site" \ -H "origin:https://bob.xx.com" \ localhost:8080/login
4. 旧版浏览器(仅 Origin):
curl -v -X POST \ -H "origin:https://client.xx.com" \ localhost:8080/login
5. 非浏览器客户端(通过):
curl -v -X POST localhost:8080/login
使用限制
当前 CrossOriginProtection 有一些限制:
- 不支持通配符:无法使用
https://*.calhoun.io匹配所有子域,必须逐个添加 - 路径级豁免:
AddInsecureBypassPattern方法用于特定路径豁免 CSRF 防护,如 OAuth 回调:
csrfProtection.AddInsecureBypassPattern("/oauth")
这会允许任何来源访问 /oauth 路径,适用于需要接受第三方回调的场景。
总结
Go 1.25 引入的 CrossOriginProtection 利用现代浏览器的 Headers 机制,大幅简化了 CSRF 防护的实现。相比传统的 Token 方案,它无需修改表单模板,只需在应用层统一配置即可。虽然对浏览器版本有一定要求,但对于大多数现代 Web 应用来说,这是一种简洁高效的防护方案。
到此这篇关于Go1.25通过Headers实现CSRF防护的文章就介绍到这了,更多相关Go CSRF防护内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!


最新评论