package main
import (
"net/http"
"time"
"github.com/gogf/csrf"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
// set cfg
func main() {
s := g.Server()
s.Group("/api.v2", func(group *ghttp.RouterGroup) {
group.Middleware(csrf.NewWithCfg(csrf.Config{
Cookie: &http.Cookie{
Name: "_csrf",// token name in cookie
Secure: true,
SameSite: http.SameSiteNoneMode,// 自定义samesite
},
ExpireTime: time.Hour * 24,
TokenLength: 32,
TokenRequestKey: "X-Token",// use this key to read token in request param
}))
group.ALL("/csrf", func(r *ghttp.Request) {
r.Response.Writeln(r.Method + ": " + r.RequestURI)
})
})
s.SetPort(8199)
s.Run()
}
11 Comments
Glider
搭配CSRF上面的範例,我從URL 輸入位置進入form 頁面,第一次我的Token value 都是空的
<input type="hidden" name="X-Token" value=""/>
重新刷新之後 才會有cookie的資料
<input type="hidden" name="X-Token" value="1I7f3s6o4GwbFyOzSnVqdMfzQrfNX4hc"/>
不知是否有人碰到?
海亮
你的用法是错误的,r.Cookie.Get是从请求(request)中读取。而中间件是将csrf信息设置到返回(response)中的。至于为什么你第二次请求可以获取,是因为第二次请求把第一次请求返回的cookies带上了。
先这样解决,增加一个函数读取中间件设置的cookies,这个函数需要在经过了csrf中间件之后调用。
Glider
感謝,我試試看
郭强
海亮
angelandy
还不不能明白这个防御的原理
浏览器又不可以自动 做sign验证
如果没理解错的话,你这个也就只能判断这个 _csrf 是否过期。
按照例子 24小时后 就会验证不过,那24小时内 还不是不安全。
既然如此,为什么不去验证 refer 而达到目的
海亮
查了一下资料,refer也是有办法绕过的,token验证是增加伪造难度。至于安全是相对的。有效期可以根据自身业务需求设置。
CSRF--花式绕过Referer技巧 - 知乎 (zhihu.com)
小陈
越了解越觉得牛逼... 一个人的知识面能这么广..
海亮
是吧,我也觉得
小陈
后来我发现你TM也牛叉, 文档, 还有很多代码, 都是你更新的.
goodhunting
把token放在cookie里没有意义啊?浏览器发送的请求不是自带cookie吗?
yidashi
cookie里的是用来校验的,用户要提交一个新的csrf表单值或者头。跨站伪造的请求没有csrf表单值和头