justinas / nosurf

CSRF protection middleware for Go.

Home Page:http://godoc.org/github.com/justinas/nosurf

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Use golang.org/x/net/context instead of gorilla based context

alitn opened this issue · comments

commented

The gorilla based context used in nosurf needs mutex locking and garbage collection. golang.org/x/net/context is a better context implementation with zero garbage collection created by go team. It'd be good to see nosurf migrating to x/net/context.

Token can be stored in the context like this:

type csrfTokenKey struct{}
...
// in the handler
c = context.WithValue(c, csrfTokenKey{}, token)

And retrieved by:

func ContextCSRFToken(c context.Context) (string, bool) {
    v, ok := c.Value(csrfTokenKey{}).(string)
    return v, ok
}

Do you not still need a map to map HTTP requests against their associated
context (token, in this case)? Which means you still need a mutex to
maintain write safety.

The context package, to my understanding, provides only the primitives.

You also don't want a token to transcend beyond the current request and be
"reused".
On Thu, 11 Jun 2015 at 9:41 am alitn notifications@github.com wrote:

The gorilla based context used in nosurf needs mutex locking and garbage
collection. golang.org/x/net/context
https://godoc.org/golang.org/x/net/context is a better context
implementation with zero garbage collection created by go team. It'd be
good to see nosurf migrating to x/net/context.

Token can be stored in the context like this:

type csrfTokenKey struct{}
...// in the handler
c = context.WithValue(c, csrfTokenKey{}, token)

And retrieved by:

func ContextCSRFToken(c context.Context) (string, bool) {
v, ok := c.Value(csrfTokenKey{}).(string)
return v, ok
}


Reply to this email directly or view it on GitHub
#28.

commented

This should be possible by passing the context as the first argument of the handler, see http://blog.golang.org/context:

At Google, we require that Go programmers pass a Context parameter as the first argument to every function on the call path between incoming and outgoing requests. [...] It [...] ensures that critical values like security credentials transit Go programs properly.

So the csrf handler will be like:

func csrfHandler(c context.Context, w http.ResponseWriter, r *http.Request) {...}

, which would make it convenient for applications that already use x/net/context by allowing to pass their existing context. Wrapping it into the standard handler is trivial:

func handler(w http.ResponseWriter, r *http.Request) {
  csrfHandler(context.Background(), w, r)
}

Seems like a nice idea, but deviates from the default net/http signature. Breaking the API for end-users at this point doesn't seem worth it.