nosurf
1.0.0
nosurf
是一个 Go 的 HTTP 包,可以帮助您防止跨站请求伪造攻击。它的作用就像一个中间件,因此基本上与任何 Go HTTP 应用程序兼容。
尽管 CSRF 是一个突出的漏洞,但 Go 的 Web 相关包基础设施主要由微框架组成,这些框架既不实现也不应该实现 CSRF 检查。
nosurf
通过提供一个CSRFHandler
来解决这个问题,该 CSRFHandler 包装您的http.Handler
并检查每个非安全(非 GET/HEAD/OPTIONS/TRACE)方法上的 CSRF 攻击。
nosurf
需要 Go 1.1 或更高版本。
支持任何http.Handler
(框架、您自己的处理程序等)并且其行为就像其本身一样。
允许通过精确的 URL、glob 或正则表达式使特定端点免受 CSRF 检查。
允许指定您自己的故障处理程序。想要向黑客展示 ASCII 中指而不是普通的老式HTTP 400
吗?没问题。
使用屏蔽令牌来减轻 BREACH 攻击。
没有 Go 标准库之外的依赖项。
package mainimport ("fmt""github.com/justinas/nosurf""html/template""net/http")var templateString string = `<!doctype html><html><body>{{ if .name }}< p>您的姓名:{{ .name }}</p>{{ end }}<form action="/" method="POST"><input type="text" name="name"><!--尝试删除它或更改其值并查看发生了什么 --><input type="hidden" name="csrf_token" value="{{ .token }}"><input type="submit" value="Send"></form></body>< /html>`var templ = template.Must(template.New("t1").Parse(templateString))func myFunc(w http.ResponseWriter, r *http.Request) {context := make(map[string]string)context["token"] = nosurf.Token(r)if r.Method == "POST" {context["name"] = r.FormValue("name") }templ.Execute(w, 上下文) }func main() {myHandler := http.HandlerFunc(myFunc)fmt.Println("监听 http://127.0.0.1:8000/")http.ListenAndServe(":8000", nosurf.New(myHandler)) }
在某些情况下,CSRF 令牌可以通过非标准方式发送,例如主体或请求是 JSON 编码消息,其中字段之一是令牌。
在这种情况下,应使用其中一种豁免方法将处理程序(路径)从自动验证中排除:
func (h *CSRFHandler) ExemptFunc(fn func(r *http.Request) bool)func (h *CSRFHandler) ExemptGlob(模式字符串)func (h *CSRFHandler) ExemptGlobs(模式 ...string)func (h *CSRFHandler) ExemptPath(路径字符串)func (h *CSRFHandler) ExemptPaths(paths ...string)func (h *CSRFHandler) ExemptRegexp(re接口{})func (h *CSRFHandler) ExemptRegexps(res ...接口{})
稍后,必须通过手动从 cookie 获取令牌并通过以下方式提供在正文中发送的令牌来验证令牌: VerifyToken(tkn, tkn2 string) bool
。
例子:
func HandleJson(w http.ResponseWriter, r *http.Request) {d := struct{X,Y intTkn string }{}json.Unmarshal(ioutil.ReadAll(r.Body), &d)if !nosurf.VerifyToken(nosurf.Token(r), d.Tkn) {http.Errorf(w, "CSRF 令牌不正确", http. StatusBadRequest)返回 }// 做点酷的事}
找到一个困扰您的问题/打开一个新问题。
讨论。
分支、提交、测试。
发出拉取请求/将提交附加到问题。