nosurf
ist ein HTTP-Paket für Go, das Ihnen hilft, Cross-Site Request Forgery-Angriffe zu verhindern. Es verhält sich wie eine Middleware und ist daher mit praktisch jeder Go-HTTP-Anwendung kompatibel.
Obwohl CSRF eine prominente Schwachstelle darstellt, besteht die webbezogene Paketinfrastruktur von Go größtenteils aus Mikro-Frameworks, die CSRF-Prüfungen weder implementieren noch implementieren sollten.
nosurf
löst dieses Problem, indem es einen CSRFHandler
bereitstellt, der Ihren http.Handler
umschließt und jede nicht sichere Methode (nicht GET/HEAD/OPTIONS/TRACE) auf CSRF-Angriffe prüft.
nosurf
erfordert Go 1.1 oder höher.
Unterstützt jeden http.Handler
(Frameworks, Ihre eigenen Handler usw.) und verhält sich selbst wie einer.
Ermöglicht das Ausschließen bestimmter Endpunkte von CSRF-Prüfungen durch eine genaue URL, einen Glob oder einen regulären Ausdruck.
Ermöglicht die Angabe Ihres eigenen Fehlerhandlers. Möchten Sie dem Hacker einen ASCII-Mittelfinger anstelle des einfachen alten HTTP 400
präsentieren? Kein Problem.
Verwendet maskierte Token, um den BREACH-Angriff abzuschwächen.
Hat keine Abhängigkeiten außerhalb der Go-Standardbibliothek.
Paket mainimport ("fmt""github.com/justinas/nosurf""html/template""net/http")var templateString string = `<!doctype html><html><body>{{ if .name }}< p>Ihr Name: {{ .name }}</p>{{ end }}<form action="/" method="POST"><input type="text" name="name"><!-- Versuchen Sie, diesen zu entfernen oder seinen Wert zu ändern und sehen Sie, was passiert --><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, context) }func main() {myHandler := http.HandlerFunc(myFunc)fmt.Println("Listening on http://127.0.0.1:8000/")http.ListenAndServe(":8000", nosurf.New(myHandler)) }
In einigen Fällen kann das CSRF-Token auf einem nicht standardmäßigen Weg gesendet werden, z. B. ist ein Text oder eine Anfrage eine JSON-codierte Nachricht, bei der eines der Felder ein Token ist.
In einem solchen Fall sollte der Handler (Pfad) von einer automatischen Überprüfung ausgeschlossen werden, indem eine der Ausnahmemethoden verwendet wird:
func (h *CSRFHandler) ExemptFunc(fn func(r *http.Request) bool)func (h *CSRFHandler) ExemptGlob(pattern string)func (h *CSRFHandler) ExemptGlobs(patterns ...string)func (h *CSRFHandler) ExemptPath(path string)func (h *CSRFHandler) ExemptPaths(paths ...string)func (h *CSRFHandler) ExemptRegexp(re interface{})func (h *CSRFHandler) ExemptRegexps(res ...interface{})
Später muss das Token überprüft werden, indem das Token manuell aus dem Cookie abgerufen und das im Textkörper gesendete Token bereitgestellt wird über: VerifyToken(tkn, tkn2 string) bool
.
Beispiel:
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-Token falsch“, http. StatusBadRequest)zurückgeben }// mach etw cool}
Finden Sie ein Problem, das Sie stört / öffnen Sie ein neues.
Diskutieren.
Abzweigen, festschreiben, testen.
Stellen Sie eine Pull-Anfrage/hängen Sie die Commits an das Problem an.