justinas/nosurf

"csrf_token" cookie being generated on exempted routes

Opened this issue · 3 comments

I am trying to exempt a few routes from csrf but noticed a "csrf_token" cookie still gets generated on those routes. Doesn't seem necessary to have that cookie on exempted routes. Also, is that cookie necessary after a form has been successfully transmitted?

An example with only 1 route that is supposed to be exempted from csrf tokens:

package main

import (
    "github.com/gorilla/mux"
    "github.com/justinas/nosurf"
    "log"
    "net/http"
)

type Routes []Route
type Route struct {
    Method      string
    Pattern     string
    HandlerFunc http.HandlerFunc
}

func mainHandler(w http.ResponseWriter, r *http.Request) {

}

func main() {
    var routes = Routes{
        Route{"GET", "/mypath", mainHandler},
    }
    router := mux.NewRouter().StrictSlash(true)
    for _, route := range routes {
        handler := route.HandlerFunc
        router.Methods(route.Method).Path(route.Pattern).Handler(handler)
    }

    // csrf protection
    csrfHandler := nosurf.New(router)
    csrfHandler.ExemptPath("/mypath")

    port := ":8080"
    log.Println("Listening at", port)
    log.Fatal(http.ListenAndServe(port, csrfHandler))
}

This behavior can be useful at times. Say, a first-time user wants to post a form from an exempted route to a protected route. Exempted route has to set the cookie, or the request will fail.

They shouldn't exempt that route then

I wouldn't be so strict about it. Say, you have a login form that is rendered on every page on the sidebar, or header, or whatever. Even on /faq/ that only serves static content. There's no need to CSRF protect a POST to /faq/ itself, since there is no form handling there, but user may want to login from /faq/.

Also, is that cookie necessary after a form has been successfully transmitted?

It's regenerated for the next request.