justinas/nosurf
justinas/nosurf has 1,756 GitHub stars and 130 forks. GitHot measured +1 stars in 24 hours. Last checked 2026-11-06 01:59 UTC. Last push 2025-05-13.
CSRF protection middleware for Go.
What you can do
- Supports any http.Handler (frameworks, your own handlers, etc.) and acts like one itself.
- Allows exempting specific endpoints from CSRF checks by an exact URL, a glob, or a regular expression.
- Allows specifying your own failure handler. Want to present the hacker with an ASCII middle finger instead of the plain old HTTP 400? No problem.
- Uses masked tokens to mitigate the BREACH attack.
Measured star growth
- in 24h
- +1
- in 7 days
- Update delayed
- in 15 days
- Update delayed
- in 1 month
- Update delayed
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
README.md
Originalnosurf
nosurf is an HTTP package for Go
that helps you prevent Cross-Site Request Forgery attacks.
It acts like a middleware and therefore
is compatible with basically any Go HTTP application.
Why?
Even though CSRF is a prominent vulnerability, Go's web-related package infrastructure mostly consists of micro-frameworks that neither do implement CSRF checks, nor should they.
nosurf solves this problem by providing a CSRFHandler
that wraps your http.Handler and checks for CSRF attacks
on every non-safe (non-GET/HEAD/OPTIONS/TRACE) method.
nosurf requires Go 1.1 or later.
Features
- Supports any
http.Handler(frameworks, your own handlers, etc.) and acts like one itself. - Allows exempting specific endpoints from CSRF checks by an exact URL, a glob, or a regular expression.
- Allows specifying your own failure handler.
Want to present the hacker with an ASCII middle finger
instead of the plain old
HTTP 400? No problem. - Uses masked tokens to mitigate the BREACH attack.
- Has no dependencies outside the Go standard library.
Example
package main
import (
"fmt"
"github.com/justinas/nosurf"
"html/template"
"net/http"
)
var templateString string = `
<!doctype html>
<html>
<body>
{{ if .name }}
<p>Your name: {{ .name }}</p>
{{ end }}
<form action="/" method="POST">
<input type="text" name="name">
<!-- Try removing this or changing its value
and see what happens -->
<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))
}
Manual token verification
In some cases the CSRF token may be send through a non standard way, e.g. a body or request is a JSON encoded message with one of the fields being a token.
In such case the handler(path) should be excluded from an automatic verification by using one of the exemption methods:
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{})
Later on, the token must be verified by manually getting the token from the cookie
and providing the token sent in body through: VerifyToken(tkn, tkn2 string) bool.
Example:
func HandleJson(w http.ResponseWriter, r *http.Request) {
d := struct{
X,Y int
Tkn string
}{}
json.Unmarshal(ioutil.ReadAll(r.Body), &d)
if !nosurf.VerifyToken(nosurf.Token(r), d.Tkn) {
http.Errorf(w, "CSRF token incorrect", http.StatusBadRequest)
return
}
// do smth cool
}
Contributing
- Find an issue that bugs you / open a new one.
- Discuss.
- Branch off, commit, test.
- Make a pull request / attach the commits to the issue.
Explore related projects
trimstray/the-book-of-secret-knowledge
A collection of inspiring lists, manuals, cheatsheets, blogs, hacks, one-liners, cli/web tools and more.
256,386 starsHack-with-Github/Awesome-Hacking
A collection of various awesome lists for hackers, pentesters and security researchers
124,736 starsswisskyrepo/PayloadsAllTheThings
A list of useful payloads and bypass for Web Application Security and Pentest/CTF
82,418 starscaddyserver/caddy
Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
78,832 stars