Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wiki page for newbies doubts and problems #52

Open
3 tasks
frederikhors opened this issue Jan 10, 2019 · 0 comments
Open
3 tasks

Wiki page for newbies doubts and problems #52

frederikhors opened this issue Jan 10, 2019 · 0 comments

Comments

@frederikhors
Copy link

frederikhors commented Jan 10, 2019

I'm newbie in everything.

I would like to write a Wiki page for newbies like me. Would you mind, @justinas?

Title: "How to use nosurf with external Single Page Application (SPA) like Ember, React, Angular or jQuery Ajax".

My app is both SPA and server rendered: authentication (using authboss - https://github.com/volatiletech/authboss) and I also have the Javascript part, so I need both the "JSON API" endpoint CSRF protected and the CSRF form values for authboss and something else server rendered.

I'm using chi router (https://github.com/go-chi/chi) like this:

package main

import (
	"net/http"
	"github.com/go-chi/chi"
)

func main() {
	r := chi.NewRouter()
        r.Use(nosurfing, addCookie)
	r.Get("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("welcome"))
	})
	http.ListenAndServe(":3000", r)
}

func Nosurfing(h http.Handler) http.Handler {
	surfing := nosurf.New(h)
	surfing.SetBaseCookie(http.Cookie{Path: "/"}) //using this just because I don't know if it's right to create a cookie for every "sub-path" like "/auth" or "/api"; I opened an issue for clarify this: https://github.com/justinas/nosurf/issues/53
	surfing.SetFailureHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Println("Failed to validate CSRF token:", nosurf.Reason(r))
		w.WriteHeader(http.StatusBadRequest)
	}))
	return surfing
}

func addCookie(handler http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		cookie := &http.Cookie{Name: "nosurf_cookie_for_ajax", Value: nosurf.Token(r), Path: "/"} //using "Path: "/"" here just because I don't know if it's right to create a cookie for every "sub-path" like "/auth" or "/api"; I opened an issue for clarify this: https://github.com/justinas/nosurf/issues/53
		http.SetCookie(w, cookie)
		handler.ServeHTTP(w, r)
	})
}

Now every time I visit a route it creates a cookie named csrf_token and one named nosurf_cookie_for_ajax.

The first one is masked and should be set HTTPOnly and the second one is different everytime and to be read from javascript which has to use it in every POST (or CSRF protected) call with request header named X-CSRF-Token.

Am I right?

The second cookie can be created maybe only if the a user is logged in (if you need this).

Default Security Settings:

I think it's good to write here also the default security settings for cookies:

type Cookie struct {
	Name  string // For cookie 1 I would use the default value. For 2 I can call it "X-CSRF-Token" as Request header needed.
	Value string // For cookie 1 default, for 2 I can use `nosurf.Token(r)`
	Path       string    // 1: "/", 2: "/" but I need to understand better this behaviour, I opened an issue about: https://github.com/justinas/nosurf/issues/53
	Domain     string    // default, like Path I think
	MaxAge   int // here I have some doubts, I think I will leave the nosurf's default for both
	Secure   bool // true (be careful if you are @ localhost)
	HttpOnly bool // true for 1 and false for 2
	SameSite SameSite // up to you, study it, helps for csrf problems
}

Summary:

  • Review the code and tell newbies if there is something bad or wrong
  • Suggest default security settings for cookies
  • Read the second article and tell newbies if it is a bad idea to use a route like /csrf for tokens

Other articles:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant