Library provides powerful stateless and fast (~638 ns/op
token generation) CSRF protection using idea of Double Submit
Token value is stored in cookie and returned to the client with header (Ex: X-CSRF-Token
).
To ensure high level of protection, tokens are changed on every request. Thus, multi-tab doesn't supporting from the box. For a good user experience developer must provide multi-tab token synchronization. It can be done using browser localStorage and StorageEvent
With a properly configured Go toolchain:
go get github.com/furdarius/csrf
Furdarius/csrf is easy to use: add the middleware to your router with the below:
// .. router init ..
handler := csrf.Middleware(csrf.Secure(cfg.IsHttps))(router)
http.ListenAndServe(":8000", handler)
Now you have ready-to-use CSRF-protection on non-safe http-methods: POST
, PUT
, PATCH
, DELETE
.
On the client side token value must be taken from the X-CSRF-Token
header. On request send it back on server as same header.
myReq.setRequestHeader("X-CSRF-Token", tokenValueHere);
You can customize setting of middleware using options.
handler := csrf.Middleware(csrf.Secure(true), csrf.MaxAge(30), csrf.CookieName("MYNAME"))
MaxAge sets the maximum age (in minutes) of a CSRF token's underlying cookie.
func MaxAge(age int) Option
Default: 1 hour.
Domain sets the cookie domain.
This should be a hostname and not a URL. If set, the domain is treated as
being prefixed with a .
- e.g. domain.io
becomes .domain.io
and
matches www.domain.io
and secure.domain.io
.
func Domain(age int) Option
Default: current domain of the request only (recommended).
Secure sets the Secure
flag on the cookie.
Set this to false
in your development environment otherwise the cookie won't
be sent over an insecure channel. Setting this via the presence of a DEV
environmental variable is a good way of making sure this won't make it to a production environment.
func Secure(s bool) Option
Default: true
(recommended).
ErrHandler allows you to change the handler called when CSRF request processing encounters an invalid token or request.
A typical use would be to provide a handler that returns a static HTML file with a HTTP 403 status.
// ErrorHandler is function using to process error in csrf protection
type ErrorHandler func(http.ResponseWriter, *http.Request, error)
func ErrHandler(h ErrorHandler) Option
By default a HTTP 403 status and a plain text CSRF failure reason are served.
RequestHeader allows you to change the request header the CSRF middleware inspects.
func RequestHeader(header string) Option
Default: X-CSRF-Token
CookieName changes the name of the CSRF cookie issued to clients.
Note that cookie names should not contain whitespace, commas, semicolons, backslashes or control characters as per RFC6265.
func CookieName(name string) Option
Default: X-CSRF-Token