gorilla/csrf provides Cross Site Request Forgery (CSRF) prevention middleware for Go web applications & services 🔒

Overview

gorilla/csrf

GoDoc Sourcegraph Reviewed by Hound CircleCI

gorilla/csrf is a HTTP middleware library that provides cross-site request forgery (CSRF) protection. It includes:

  • The csrf.Protect middleware/handler provides CSRF protection on routes attached to a router or a sub-router.
  • A csrf.Token function that provides the token to pass into your response, whether that be a HTML form or a JSON response body.
  • ... and a csrf.TemplateField helper that you can pass into your html/template templates to replace a {{ .csrfField }} template tag with a hidden input field.

gorilla/csrf is designed to work with any Go web framework, including:

gorilla/csrf is also compatible with middleware 'helper' libraries like Alice and Negroni.

Contents

Install

With a properly configured Go toolchain:

go get github.com/gorilla/csrf

Examples

gorilla/csrf is easy to use: add the middleware to your router with the below:

CSRF := csrf.Protect([]byte("32-byte-long-auth-key"))
http.ListenAndServe(":8000", CSRF(r))

...and then collect the token with csrf.Token(r) in your handlers before passing it to the template, JSON body or HTTP header (see below).

Note that the authentication key passed to csrf.Protect([]byte(key)) should be 32-bytes long and persist across application restarts. Generating a random key won't allow you to authenticate existing cookies and will break your CSRF validation.

gorilla/csrf inspects the HTTP headers (first) and form body (second) on subsequent POST/PUT/PATCH/DELETE/etc. requests for the token.

HTML Forms

Here's the common use-case: HTML forms you want to provide CSRF protection for, in order to protect malicious POST requests being made:

package main

import (
    "net/http"

    "github.com/gorilla/csrf"
    "github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/signup", ShowSignupForm)
    // All POST requests without a valid token will return HTTP 403 Forbidden.
    // We should also ensure that our mutating (non-idempotent) handler only
    // matches on POST requests. We can check that here, at the router level, or
    // within the handler itself via r.Method.
    r.HandleFunc("/signup/post", SubmitSignupForm).Methods("POST")

    // Add the middleware to your router by wrapping it.
    http.ListenAndServe(":8000",
        csrf.Protect([]byte("32-byte-long-auth-key"))(r))
    // PS: Don't forget to pass csrf.Secure(false) if you're developing locally
    // over plain HTTP (just don't leave it on in production).
}

func ShowSignupForm(w http.ResponseWriter, r *http.Request) {
    // signup_form.tmpl just needs a {{ .csrfField }} template tag for
    // csrf.TemplateField to inject the CSRF token into. Easy!
    t.ExecuteTemplate(w, "signup_form.tmpl", map[string]interface{}{
        csrf.TemplateTag: csrf.TemplateField(r),
    })
    // We could also retrieve the token directly from csrf.Token(r) and
    // set it in the request header - w.Header.Set("X-CSRF-Token", token)
    // This is useful if you're sending JSON to clients or a front-end JavaScript
    // framework.
}

func SubmitSignupForm(w http.ResponseWriter, r *http.Request) {
    // We can trust that requests making it this far have satisfied
    // our CSRF protection requirements.
}

Note that the CSRF middleware will (by necessity) consume the request body if the token is passed via POST form values. If you need to consume this in your handler, insert your own middleware earlier in the chain to capture the request body.

JavaScript Applications

This approach is useful if you're using a front-end JavaScript framework like React, Ember or Angular, and are providing a JSON API. Specifically, we need to provide a way for our front-end fetch/AJAX calls to pass the token on each fetch (AJAX/XMLHttpRequest) request. We achieve this by:

  • Parsing the token from the <input> field generated by the csrf.TemplateField(r) helper, or passing it back in a response header.
  • Sending this token back on every request
  • Ensuring our cookie is attached to the request so that the form/header value can be compared to the cookie value.

We'll also look at applying selective CSRF protection using gorilla/mux's sub-routers, as we don't handle any POST/PUT/DELETE requests with our top-level router.

package main

import (
    "github.com/gorilla/csrf"
    "github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()
    csrfMiddleware := csrf.Protect([]byte("32-byte-long-auth-key"))

    api := r.PathPrefix("/api").Subrouter()
    api.Use(csrfMiddleware)
    api.HandleFunc("/user/{id}", GetUser).Methods("GET")

    http.ListenAndServe(":8000", r)
}

func GetUser(w http.ResponseWriter, r *http.Request) {
    // Authenticate the request, get the id from the route params,
    // and fetch the user from the DB, etc.

    // Get the token and pass it in the CSRF header. Our JSON-speaking client
    // or JavaScript framework can now read the header and return the token in
    // in its own "X-CSRF-Token" request header on the subsequent POST.
    w.Header().Set("X-CSRF-Token", csrf.Token(r))
    b, err := json.Marshal(user)
    if err != nil {
        http.Error(w, err.Error(), 500)
        return
    }

    w.Write(b)
}

In our JavaScript application, we should read the token from the response headers and pass it in a request header for all requests. Here's what that looks like when using Axios, a popular JavaScript HTTP client library:

// You can alternatively parse the response header for the X-CSRF-Token, and
// store that instead, if you followed the steps above to write the token to a
// response header.
let csrfToken = document.getElementsByName("gorilla.csrf.Token")[0].value

// via https://github.com/axios/axios#creating-an-instance
const instance = axios.create({
  baseURL: "https://example.com/api/",
  timeout: 1000,
  headers: { "X-CSRF-Token": csrfToken }
})

// Now, any HTTP request you make will include the csrfToken from the page,
// provided you update the csrfToken variable for each render.
try {
  let resp = await instance.post(endpoint, formData)
  // Do something with resp
} catch (err) {
  // Handle the exception
}

If you plan to host your JavaScript application on another domain, you can use the Trusted Origins feature to allow the host of your JavaScript application to make requests to your Go application. Observe the example below:

package main

import (
    "github.com/gorilla/csrf"
    "github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()
    csrfMiddleware := csrf.Protect([]byte("32-byte-long-auth-key"), csrf.TrustedOrigins([]string{"ui.domain.com"}))

    api := r.PathPrefix("/api").Subrouter()
    api.Use(csrfMiddleware)
    api.HandleFunc("/user/{id}", GetUser).Methods("GET")

    http.ListenAndServe(":8000", r)
}

func GetUser(w http.ResponseWriter, r *http.Request) {
    // Authenticate the request, get the id from the route params,
    // and fetch the user from the DB, etc.

    // Get the token and pass it in the CSRF header. Our JSON-speaking client
    // or JavaScript framework can now read the header and return the token in
    // in its own "X-CSRF-Token" request header on the subsequent POST.
    w.Header().Set("X-CSRF-Token", csrf.Token(r))
    b, err := json.Marshal(user)
    if err != nil {
        http.Error(w, err.Error(), 500)
        return
    }

    w.Write(b)
}

On the example above, you're authorizing requests from ui.domain.com to make valid CSRF requests to your application, so you can have your API server on another domain without problems.

Google App Engine

If you're using Google App Engine, (first-generation) which doesn't allow you to hook into the default http.ServeMux directly, you can still use gorilla/csrf (and gorilla/mux):

package app

// Remember: appengine has its own package main
func init() {
    r := mux.NewRouter()
    r.HandleFunc("/", IndexHandler)
    // ...

    // We pass our CSRF-protected router to the DefaultServeMux
    http.Handle("/", csrf.Protect([]byte(your-key))(r))
}

Note: You can ignore this if you're using the second-generation Go runtime on App Engine (Go 1.11 and above).

Setting SameSite

Go 1.11 introduced the option to set the SameSite attribute in cookies. This is valuable if a developer wants to instruct a browser to not include cookies during a cross site request. SameSiteStrictMode prevents all cross site requests from including the cookie. SameSiteLaxMode prevents CSRF prone requests (POST) from including the cookie but allows the cookie to be included in GET requests to support external linking.

func main() {
    CSRF := csrf.Protect(
      []byte("a-32-byte-long-key-goes-here"),
      // instruct the browser to never send cookies during cross site requests
      csrf.SameSite(csrf.SameSiteStrictMode),
    )

    r := mux.NewRouter()
    r.HandleFunc("/signup", GetSignupForm)
    r.HandleFunc("/signup/post", PostSignupForm)

    http.ListenAndServe(":8000", CSRF(r))
}

Setting Options

What about providing your own error handler and changing the HTTP header the package inspects on requests? (i.e. an existing API you're porting to Go). Well, gorilla/csrf provides options for changing these as you see fit:

func main() {
    CSRF := csrf.Protect(
            []byte("a-32-byte-long-key-goes-here"),
            csrf.RequestHeader("Authenticity-Token"),
            csrf.FieldName("authenticity_token"),
            csrf.ErrorHandler(http.HandlerFunc(serverError(403))),
    )

    r := mux.NewRouter()
    r.HandleFunc("/signup", GetSignupForm)
    r.HandleFunc("/signup/post", PostSignupForm)

    http.ListenAndServe(":8000", CSRF(r))
}

Not too bad, right?

If there's something you're confused about or a feature you would like to see added, open an issue.

Design Notes

Getting CSRF protection right is important, so here's some background:

  • This library generates unique-per-request (masked) tokens as a mitigation against the BREACH attack.
  • The 'base' (unmasked) token is stored in the session, which means that multiple browser tabs won't cause a user problems as their per-request token is compared with the base token.
  • Operates on a "whitelist only" approach where safe (non-mutating) HTTP methods (GET, HEAD, OPTIONS, TRACE) are the only methods where token validation is not enforced.
  • The design is based on the battle-tested Django and Ruby on Rails approaches.
  • Cookies are authenticated and based on the securecookie library. They're also Secure (issued over HTTPS only) and are HttpOnly by default, because sane defaults are important.
  • Cookie SameSite attribute (prevents cookies from being sent by a browser during cross site requests) are not set by default to maintain backwards compatibility for legacy systems. The SameSite attribute can be set with the SameSite option.
  • Go's crypto/rand library is used to generate the 32 byte (256 bit) tokens and the one-time-pad used for masking them.

This library does not seek to be adventurous.

License

BSD licensed. See the LICENSE file for details.

Comments
  • Getting 'Forbidden - CSRF token invalid' while sending Ajax POST request using javascript XMLHttpRequest()

    Getting 'Forbidden - CSRF token invalid' while sending Ajax POST request using javascript XMLHttpRequest()

    Hello, please I need help am sending many Ajax requests on my application and am making use of csrf, but some of the ajax requests returns 'Forbidden - CSRF token invalid' while some goes through without any issues and I have made sure that the javascript script code are the same on all the requests only changing the handler that each calls but still can't figure out while some don't go through, the ones am using through hidden input on forms goes through as well without any issue, my code snippet is below.

    var crsfValue = document.getElementsByTagName('meta')['gorilla.csrf.Token'].getAttribute('content');
                var xhr = new XMLHttpRequest();
                xhr.open('POST', '/Device/UnLock');
                xhr.setRequestHeader('X-CSRF-Token',crsfValue);
                xhr.send(clicked);
    

    Meanwhile, I always load the token using a meta tag on the head of my master page

    question stale 
    opened by Kenmobility 19
  • [question] XHR + CSRF questions

    [question] XHR + CSRF questions

    For example, in terms of your "JavaScript Applications" example, suppose an attacker manages to let a user of the target website click a link leading to a page of the attacker's website, which in turn make the following request (I use conceptual code) to the target website (assuming that the url which supplying the innital token is 'https://target-site.com/get/token'):

    fetch('https://target-site.com/get/token')
    .then(token => {
      // request the target website do something bad with the token
      fetch('https://target-site.com/do/something/bad', {
        method: 'post',
        headers: { "X-CSRF-Token": token},
        credentials: 'include'
      })
    })
    
    question 
    opened by bigradish 15
  • Clearing `_gorilla_csrf` cookie not regenerating

    Clearing `_gorilla_csrf` cookie not regenerating

    Hi there, I'm having trouble with the secure cookie _gorilla_csrf regenerating when I clear out the cookie from browser. I notice it only regenerates after a POST which would obviously fail and return a 403 error. I also notice that the cookie doesn't get set on page load as well.

    More context:

    • Working with a Single Page App, React
    • Using Goji for handling multiple routes
    • Passing in csrf.Protect() middleware to Goji at the root route

    Any idea what's going on?

    Any help would be appreciated!

    question stale 
    opened by donaldthai 14
  • [question]: Ability to ignore certain POST requests ?

    [question]: Ability to ignore certain POST requests ?

    I want to have an API structure like this

    (unauthenticated)
    /register
    /login
    
    (authenticated)
    /logout
    /api/*
    

    But since both /register and /login will send data to the server, I want them to be POST requests. Now IIUC, csrf will verify all POST requests, and also it will match the cookie only for the path and its subpaths from which it was originally issued.

    Otherwise, my endpoints will look like /login/api/dothis, /login/api/dothat which will make it look very weird.

    I guess I have 2 questions -

    1. Is it possible to ignore validation on certain POST requests ?
    2. Is it possible to use a token from one path on another path ?
    opened by agnivade 13
  • complete example

    complete example

    I can't quite get the example to work, and I keep getting Forbidden - CSRF token invalid. I'm using HTML form as illustrated and I did see an hidden input field of gorilla.csrf.Token with its value.

    am I missing something? can there be a complete example? thank you~

    ps. I even tried the example here: http://www.gorillatoolkit.org/pkg/csrf

    question 
    opened by proclaim 12
  • CSRF 处理 multipart/form-data 的问题

    CSRF 处理 multipart/form-data 的问题

    当时使用 PathPrefix 的时候,CSRF 会失效,比如以下代码:

    CSRF := csrf.Protect( []byte("a-32-byte-long-key-goes-here"), )

    router := mux.NewRouter() router.HandleFunc("/front/", controller.FontIndex)

    adminRoutes := mux.NewRouter() adminRoutes.HandleFunc("/admin/form", controller.AdminForm)

    router.PathPrefix("/admin").Handler(negroni.New( negroni.NewRecovery(), middleware.NewCheckLogin(), negroni.Wrap(adminRoutes), ))

    n := negroni.New( negroni.NewRecovery(), )

    n.UseHandler(CSRF(router))

    log.Fatal(http.ListenAndServe(":3001", n))

    访问 http://domain/front ,CSRF是可以用的,但如果访问 http://domain/admin/form ,这时 CSRF 会失效。

    opened by panjunjie 12
  • [question] X-Csrf-Token is empty in Response headers (Secure is off)

    [question] X-Csrf-Token is empty in Response headers (Secure is off)

    Yes, my "secure" setting is set to false :)

    Using github.com/gorilla/csrf v1.7.0 and go 1.14

    I have the set up: app.localhost.com calls api.localhost.com

    Problem: Stated in title, my Response headers look like this:

    HTTP/1.1 200 OK
    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Origin: http://app.localhost.com
    Access-Control-Expose-Headers: *
    Content-Length: 0
    Date: Mon, 10 Aug 2020 17:07:37 GMT
    Set-Cookie: testCookie=there; Domain=localhost.com; Expires=Mon, 10 Aug 2020 17:37:37 GMT; HttpOnly
    Set-Cookie: _gorilla_csrf=MTU5NzA3OTI1N3xJamRvUWxwdVlVSmlaRWRqVWpkSmJVRldNRzFtVFcxUmNEbEhSQ3RZVGs5aFYyZ3hRa1JrYzNCQk5EQTlJZ289fDhJXLZGYzxZ9ctPZcVEiV3JvgsZ9VVc-55nWhOcucz-; Domain=localhost.com; Expires=Tue, 11 Aug 2020 05:07:37 GMT; Max-Age=43200; HttpOnly; SameSite=Lax
    Vary: Origin
    X-Csrf-Token:  // Problem right here
    Xcrsf: hello!  // Shows that I can set a header
    

    My (pared down) server code looks like this:

    func main() {
    
    	r := chi.NewRouter()
    	r.Use(middleware.Recoverer)
    	r.Use(middleware.Logger)
    	r.Use(middleware.Timeout(30 * time.Second))
    	r.Use(httprate.LimitByIP(100, 1*time.Minute))
    
    	r.Use(cors.New(cors.Options{
    		AllowedOrigins:   []string{"http://app.localhost.com", "http://api.localhost.com"},
    		AllowCredentials: true,
    		Debug:            true,
    		AllowedHeaders:   []string{"Content-Type", "Sentry-Trace", "X-CSRF-Token"},
    		//AllowedHeaders:   []string{"*"},
    		MaxAge:           300,
    		ExposedHeaders: []string{"*"},
    	}).Handler)
    	r.Use(AddUserIDToCTX())
    
    	port := os.Getenv("PORT")
    	if port == "" {
    		port = defaultPort
    	}
    
    	csrfMiddleware := csrf.Protect([]byte("AB4F63F9AC65152575886860DDE480A1"),
    		csrf.TrustedOrigins([]string{"localhost.com"}),
    		csrf.Secure(false),
    		csrf.ErrorHandler(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
    			fmt.Printf("failed CSRF - %s", csrf.FailureReason(req))
    		})),
    	)
    	r.Use(csrfMiddleware)
    
    	r.Route("/graphql", func(r chi.Router) {
                 // graphql stuff
    	})
    
    	panic(http.ListenAndServe("0.0.0.0:8089", appdb.SessionManager.LoadAndSave(r)))
    }
    

    And then I set the header in my session middleware:

    //// Middleware decodes the share session cookie and packs the session into context
    func AddUserIDToCTX() func(http.Handler) http.Handler {
    	return func(next http.Handler) http.Handler {
    		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    
    			// Add CSRF Token on each request
    			w.Header().Set("X-CSRF-Token", csrf.Token(r))
    			w.Header().Set("xcrsf", "hello!")
    			// Session stuff below
    		})
    	}
    }
    

    Any idea why my header won't get set? Should I share my Traefik config?

    Ps. Love listening to the Gorilla team on the Go Time podcast!

    question stale 
    opened by austincollinpena 10
  • csrf.Token() returns an empty token, even though _gorilla_csrf cookie is set

    csrf.Token() returns an empty token, even though _gorilla_csrf cookie is set

    I'm having trouble getting the Token() helper function to work.

    I've wrapped my root-level handler with a csrf.Protect handler, which seems to work. The handler rejects requests that don't specify the correct token, and also sets the _gorilla_csrf cookie on GET requests.

    But when I use csrf.Token for setting X-CSRF-Token as described in the docs, I get an empty string.

    Looking at the function it seems that an empty string will be returned if the context store does not contain the token secret. But I don't understand how that can be when I'm also getting the _gorilla_csrf cookie set to a non-empty value.

    Any pointers or clarification would be greatly appreciated.

    opened by echlebek 10
  • [bug] CSRF verification fail if requests takes too long

    [bug] CSRF verification fail if requests takes too long

    Describe the bug CSRF verification fail if requests takes too long

    …

    Versions

    Go version: go version go version go version go1.13.6 linux/amd64

    package version: run git rev-parse HEAD inside the repo [email protected] 12:53 ~/g/s/g/g/csrf master> git rev-parse HEAD 4b50158aba1b9683db9b198ddc61436713e778f8 [email protected] 12:53 ~/g/s/g/g/csrf master>

    …

    Steps to Reproduce I use the upload features in my app. When uploading small files - or doing any other form activities it works fine. The same session try to upload a large file (2.7G) when upload finsihed the app return CSRF invalid token error.

    If I run it in the local development box and upload the same file which is much faster the error does not happen.

    I suspects it has a timeout settings somewhere but searching around does not give me the answer yet.

    Is there any timeout at the server when a csrf token is sumitted and failed to verify?

    Thanks

    …

    Expected behavior

    What output or behaviour were you expecting instead?

    …

    Code Snippets

    A minimum viable code snippet can be useful! (use backticks to format it).

    …

    question 
    opened by sunshine69 9
  • Using same csrf token for form and api calls from js side

    Using same csrf token for form and api calls from js side

    Hello, guys!

    I'm developing an SPA application. Its uses an auth token and csrf token.

    So have added an hidden field with csrf token to my index.html file. Then, when i'm creating an http request i'm parsing value from this hidden field and add this token to request headers.

    But each time it fails.

    so. my server:

    func NewServer() *Server {
    	csrfMiddleware := csrf.Protect(
    		[]byte("32-byte-long-auth-key"),
    	)
    
    	router := mux.NewRouter()
    	fs := http.FileServer(http.Dir(server.config.StaticDir))
    
    	apiController := consoleapi.NewController()
    	apiRouter := router.PathPrefix("/api/v0/controller").Subrouter()
    	apiRouter.Use(csrfMiddleware)
    	apiRouter.HandleFunc("/api-call", apiController.Call).Methods(http.MethodPost)
    	
    	// handler for index.html
            router.PathPrefix("/").Handler(csrfMiddleware(http.HandlerFunc(server.appHandler)))
    
    	server.server = http.Server{
    		Handler:        router,
    	}
    
    	return &server
    }
    
    func (server *Server) appHandler(w http.ResponseWriter, r *http.Request) {
    	var data struct {
    		CsrfTag            template.HTML
    	}
    
    	data.CsrfTag = csrf.TemplateField(r)
    
            // executing index template 
    	server.templates.index.Execute(w, data) 
    }
    

    So, my hidden input creates successfully with needed token value.

    <input type="hidden" name="gorilla.csrf.Token" value="CSRF_TOKEN">
    

    and each time before executing an api call i do next:

    const csrfToken = (document.getElementsByName("gorilla.csrf.Token")[0] as any).value;
    const headers: Record<string, string> = {
              ...
                'X-CSRF-Token': csrfToken,
            };
    

    …

    Versions

    Go version: go version go1.13.4 linux/amd64

    package version: v1.6.2 …

    question 
    opened by crawter 9
  • Forbidden - CSRF token invalid

    Forbidden - CSRF token invalid

    Sorry for the support question here. I can't get it working. Can you see what I've done wrong here please?

    https://s.natalian.org/2017-12-12/invalid.txt

    question 
    opened by kaihendry 9
  • [bug] Generate CSRF tokens for skipped requests

    [bug] Generate CSRF tokens for skipped requests

    Describe the bug

    (First off, I'm not 100% whether this is a bug, a feature request, or me not understanding something, so apologies if I categorized it incorrectly).

    I have a REST API that uses JWT authentication for non-browser clients, but want to support cookie-based authentication for web clients. To support this, I am calling UnsafeSkipCheck if no authentication / session cookie is present in the request (and JWT authentication will be used instead where I do not worry about CSRF).

    However, calling UnsafeSkipCheck exits so early that no CSRF token is ever generated, which means that GET requests will not be responded to with a X-CSRF-Token header, and the client has essentially no way of obtaining a CSRF token.

    Is there a reason why skipping the check prevents a token from being generated altogether? Am I just approaching this wrong?

    I can call UnsafeSkipCheck much more selectively to bypass this issue, but that doesn't feel correct.

    Versions

    Go version: go version go1.19 darwin/arm64 package version: v1.7.1

    bug 
    opened by Airblader 0
  • issues/158/examples for working api with javascript frontend

    issues/158/examples for working api with javascript frontend

    Fixes #158, which is essentially that

    1. none of the examples in the README for working with a JavaScript frontend will work without proper CORS config on the backend
    2. there is no example at all for using the HTTP header instead of getting the CSRF token from the hidden form field

    Summary of Changes

    I have merged/copied over these simplified examples from my own repository of working examples.

    I was not sure how the maintainers may want to reference these examples in the main README. Copying them over to the README verbatim would be putting a lot of code into the README, but without changing the current README, the content there differs significantly from the examples.

    opened by francoposa 1
Releases(v1.7.1)
  • v1.7.1(Jul 29, 2021)

    v1.7.1 is a minor maintenance release. It improves documentation, and fixes a bug (#149) that caused missing tokens to not provide a clear error message back to the client.

    CHANGELOG

    • bugfix: Not providing any token in requests results in wrong error message (#149)
    • Add a note about secrecy of CSRF token in the README.md (#154) @maxximino
    • Add note about csrf.Path option (#147) @karelbilek
    • build: use build matrix; drop Go <= 1.10 (#142) @elithrar
    • docs: change TrustedOrigin to TrustedOrigins in README (#140) @mittonface
    • docs: add TOC to README (#137) @elithrar
    Source code(tar.gz)
    Source code(zip)
  • v1.7.0(Apr 26, 2020)

    📢 This release of gorilla/csrf changes the default SameSite cookie attribute to address changes in the SameSite spec (see https://github.com/golang/go/issues/36990)

    Previously: The SameSiteDefaultMode in csrf (prior to v1.7.0) would set SameSite on the cookie, which is not valid in some browsers, notably older versions of Chrome/Android. These browsers would not set cookies with this "invalid" attribute. Now: The default mode is SameSite=Lax, which is supported by Chrome v51, Firefox v60, Safari v13 and most recent browsers.

    If you're new to SameSite, read the MDN documentation for a great overview on why this attribute helps prevent cookies from being 'leaked' to third-party domains unintentionally.

    CHANGELOG

    • Set SameSite=Lax by default (#136) @elithrar
    • Don't set a default samesite for backwards compatibility (#132) @euank
    Source code(tar.gz)
    Source code(zip)
  • v1.6.2(Nov 21, 2019)

  • v1.6.1(Aug 26, 2019)

    Notable Changes

    🆕 This release introduces the TrustedOrigins option, which allows a user to explicitly trust specific Referers. This simplifies the use of this library when the backend domain (issuing the cookie) does not match the front-end domain, such as in Single Page Application architectures.

    🐞 This release also fixes a regression to applying the default cookie MaxAge (cookies were only session cookies). This would typically have been unnoticed by most users as the CSRF middleware resets the cookie on each request.

    CHANGELOG

    • bugfix: correctly set a defaultMaxAge when MaxAge isn't called (#120) @elithrar
    • Create release-drafter.yml (#118) @elithrar
    • Add trusted origins feature (#117) @fjorgemota
    • Add CircleCI status badge to README (#113) @elithrar
    Source code(tar.gz)
    Source code(zip)
  • v1.6.0(Jun 26, 2019)

    Notable Changes

    • We've removed support for versions of Go prior to v1.7 - v1.6 was released over 3.5 years ago (@kisielk making me feel old!)
    • As a result, we've also removed gorilla/context as a dependency, since Go 1.7+ has its own http.Request.Context() implementation
    • Moved our CI to CircleCI - you can see the build dashboard here

    CHANGELOG

    38c9e46 Remove gorilla/context as part of pre-1.7 support (#114) 3719438 (elithrar/go-mod) [build] Add CircleCI config (#112) d162037 [docs] Improve JS header/form instructions (#103)
    40703b8 Update and rename stale to stale.yml (#102) 1db7df7 Merge pull request #101 from gorilla/stalebot 472e852 [docs] Add a "Reviewed by Hound" badge (#98) abcfd25 (origin/stalebot) Add stalebot config f903b4e README.md: Update site URL 10bfafc [docs] Note that developers should check the HTTP method (#91) d690280 Merge pull request #88 from gorilla/elithrar/corporate-overlords

    Source code(tar.gz)
    Source code(zip)
  • v1.5.1(May 22, 2018)

  • v1.5(Jan 8, 2017)

    Uses the new request.Context from Go 1.7 for Go 1.7 automatically. Note that gorilla/context is incompatible with Go 1.7.

    6958173 [doc] Fixed readme mux path prefix (#51) 10e8fd1 [docs] Fix a few minor typos in examples. (#54) fdae182 docs: fix minor typo (#50) 7f54448 [docs] Fix incorrect function name in docs (#49) bbe6687 [docs] Fix syntax typo (#48) 0ff6a2c [docs] Improve commented code (#46) a8abe8a [docs] Mentions passing csrf.Secure(false) in local dev environments. a9c30ae [bugfix] Remove dependency on gorilla/context for go1.7+ (#42) 4642ecf [bugfix] Support a cookie MaxAge of 0. (#39) 101aaa4 Merge branch 'master' of github.com:gorilla/csrf 2a06c32 [ci] Add 1.6; skip install block; don't simplify. 0bb4971 [deps] Move from errors -> github.com/pkg/errors dd1bce8 [deps] Move from errors -> github.com/pkg/errors

    Source code(tar.gz)
    Source code(zip)
  • v1.4(Jun 2, 2016)

    • With Go 1.7's net/http package growing support for context.Context as part of http.Request, gorilla/csrf now uses the context to pass CSRF tokens and other metadata alongside the request instead of gorilla/context.
    • NOTE: There is a minor breaking change with UnsafeSkipCheck - it now returns a *http.Request. Existing applications will "fail closed" (i.e. CSRF will be enforced again). Since this was a relatively new feature (less than a week old) the impact of this should be very minor.
    Source code(tar.gz)
    Source code(zip)
  • v1.3(Feb 24, 2016)

    v1.3 includes an important security fix for users of Go 1.2 (Debian <=7, Ubuntu <=14.10, etc.). This would cause token comparison to fail: https://groups.google.com/forum/#!topic/gorilla-web/G3aIFrm0LVI

    CHANGELOG:

    • [bugfix] Token comparison could fail on versions of Go < 1.3.
    • [ci] Updated Travis to use matrix builds.
    Source code(tar.gz)
    Source code(zip)
  • v1.2(Dec 6, 2015)

    CHANGELOG:

    • [feature] Custom field names are now passed to TemplateField implicitly.
    • [feature] Expose an Option type for building functional options.
    • [ci] Run go vet, gofmt and the race detector during tests

    ADDENDUM:

    Note that gorilla/csrf respects SemVer as defined at http://semver.org/ but will not make backward-incompatible changes unless a security fix requires it (which is extremely unlikely given the small API of the package!). "MINOR" versions as defined in SemVer will encapsulate additions to the API or resolving implicit behaviour, whereas "PATCH" versions will typically encapsulate documentation changes or clarifications.

    Source code(tar.gz)
    Source code(zip)
Owner
Gorilla Web Toolkit
Gorilla is a web toolkit for the Go programming language that provides useful, composable packages for writing HTTP-based applications.
Gorilla Web Toolkit
A Go middleware that stores various information about your web application (response time, status code count, etc.)

Go stats handler stats is a net/http handler in golang reporting various metrics about your web application. This middleware has been developed and re

Florent Messa 587 Nov 25, 2022
A golang registry for global request variables.

context ?? This library is in maintenance mode. ⚠ ⚠ ⚠ Note ⚠ ⚠ ⚠ gorilla/context, having been born well before context.Context existed, does not play

Gorilla Web Toolkit 415 Oct 27, 2022
A http service to verify request and bounce them according to decisions made by CrowdSec.

traefik-crowdsec-bouncer A http service to verify request and bounce them according to decisions made by CrowdSec. Description This repository aim to

Fabien Bonalair 166 Nov 23, 2022
There are http server which handle transaction request(like: SET,GET,DELETE)

Loco_test_assesment There are http server which handle transaction request(like: SET,GET,DELETE) File "Backend Assessment.docx" has the proper informa

kumari tanushree 0 Jan 14, 2022
Painless middleware chaining for Go

Alice Alice provides a convenient way to chain your HTTP middleware functions and the app handler. In short, it transforms Middleware1(Middleware2(Mid

Justinas Stankevičius 2.7k Nov 24, 2022
Go http.Hander based middleware stack with context sharing

wrap Package wrap creates a fast and flexible middleware stack for http.Handlers. Features small; core is only 13 LOC based on http.Handler interface;

go-on - web toolkit in Go 59 Apr 5, 2022
Minimalist net/http middleware for golang

interpose Interpose is a minimalist net/http middleware framework for golang. It uses http.Handler as its core unit of functionality, minimizing compl

James Pirruccello 296 Sep 27, 2022
Lightweight Middleware for net/http

MuxChain MuxChain is a small package designed to complement net/http for specifying chains of handlers. With it, you can succinctly compose layers of

Stephen Searles 209 Oct 19, 2022
Idiomatic HTTP Middleware for Golang

Negroni Notice: This is the library formerly known as github.com/codegangsta/negroni -- Github will automatically redirect requests to this repository

null 7.3k Nov 20, 2022
A tiny http middleware for Golang with added handlers for common needs.

rye A simple library to support http services. Currently, rye provides a middleware handler which can be used to chain http handlers together while pr

InVision 98 Sep 27, 2022
Simple middleware to rate-limit HTTP requests.

Tollbooth This is a generic middleware to rate-limit HTTP requests. NOTE 1: This library is considered finished. NOTE 2: Major version changes are bac

Didip Kerabat 2.3k Nov 22, 2022
OpenID Connect (OIDC) http middleware for Go

Go OpenID Connect (OIDC) HTTP Middleware Introduction This is a middleware for http to make it easy to use OpenID Connect. Currently Supported framewo

Xenit AB 68 Nov 27, 2022
Go HTTP middleware to filter clients by IP

Go HTTP middleware to filter clients by IP

cristaltech 4 Oct 30, 2022
Chi ip banner is a chi middleware that bans some ips from your Chi http server.

Chi Ip Banner Chi ip banner is a chi middleware that bans some ips from your Chi http server. It reads a .txt file in your project's root, called bani

null 1 Jan 4, 2022
URL Rewrite middleware for gin

Url Rewrite middleware for gin Example In this exable these urls use the same route http://localhost:1234/test-me http://localhost:1234/index.php/test

Lucian I. Last 3 Sep 15, 2022
A customized middleware of DAPR.

A customized middleware of DAPR.

Gatty 1 Dec 24, 2021
Gin middleware for session.

wsession Gin middleware for session management with multi-backend support: cookie-based Redis memstore Usage Start using it Download and install it: g

null 0 Jan 9, 2022
Fiber middleware for server-timing

Server Timing This is a Fiber middleware for the [W3C Server-Timing API] based on mitchellh/go-server-timing

Vlad Fratila 0 Feb 6, 2022
gorilla/csrf provides Cross Site Request Forgery (CSRF) prevention middleware for Go web applications & services 🔒

gorilla/csrf gorilla/csrf is a HTTP middleware library that provides cross-site request forgery (CSRF) protection. It includes: The csrf.Protect middl

Gorilla Web Toolkit 854 Nov 25, 2022
golang csrf react example, using gorilla/mux and gorilla/mux

Demo REST backend Gorilla csrf middleware and Js frontend Use gorilla/mux and gorilla/csrf How to run open goland IDE, run middleware_test.go by click

Mike Cat 0 Feb 2, 2022