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(路徑 ...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)返回 }// 做點酷的事}
找到一個困擾您的問題/打開一個新問題。
討論。
分支、提交、測試。
發出拉取請求/將提交附加到問題。