func TestCSRFTokenBackend(t *testing.T) { var cookieName = "test" // Create a cookiestore store := sessions.NewCookieStore([]byte("secret-key")) // Create the recorder w := httptest.NewRecorder() // Create the handler h := New(http.HandlerFunc(successHandler), store, cookieName) // Create the form form := url.Values{} // Create the POST request req, err := http.NewRequest("POST", "http://localhost/", bytes.NewBufferString(form.Encode())) if err != nil { panic(err) } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") // Run the page h.ServeHTTP(w, req) if w.Code == 200 { t.Errorf("The request should have failed, but it didn't. Instead, the code was %d", w.Code) } }
func main() { // Create cookie store Store = sessions.NewCookieStore([]byte("This is super screen...")) Store.Options = &sessions.Options{ //Domain: "localhost", // Chrome doesn't work with localhost domain Path: "/", MaxAge: 3600 * 8, // 8 hours HttpOnly: true, } // Default handler h := http.HandlerFunc(routeLogin) // Prevents CSRF cs := csrfbanana.New(h, Store, SessionName) // Set error page for CSRF cs.FailureHandler(http.HandlerFunc(routeInvalidToken)) // Generate a new token after each check (also prevents double submits) cs.ClearAfterUsage(true) // Exclude /static/ from tokens (even though we don't have a static file handler...) cs.ExcludeRegexPaths([]string{"/static(.*)"}) // Optional - set the token length csrfbanana.TokenLength = 32 // Optional - set the token name used in the forms csrfbanana.TokenName = "token" fmt.Println("Listening on http://localhost:80/") http.ListenAndServe(":80", cs) }
func TestClear(t *testing.T) { var cookieName = "test" // Create a cookiestore store := sessions.NewCookieStore([]byte("secret-key")) // Create the recorder w := httptest.NewRecorder() // Create the request r := fakeGet() // Get the session sess, err := store.Get(r, cookieName) if err != nil { t.Fatalf("Error getting session: %v", err) } // Generate a token Token(w, r, sess) // Clear the token Clear(w, r, sess) if _, ok := sess.Values[TokenName]; ok { t.Errorf("StringMap should not exist: expected %v, got %v", nil, reflect.TypeOf(sess.Values[TokenName])) } }
func TestTokenWithPathMaxTokens(t *testing.T) { var cookieName = "test" // Create a cookiestore store := sessions.NewCookieStore([]byte("secret-key")) // Create the recorder w := httptest.NewRecorder() // Create the request r := fakeGet() // Get the session sess, err := store.Get(r, cookieName) if err != nil { t.Fatalf("Error getting session: %v", err) } for i := 0; i < MaxTokens; i++ { TokenWithPath(w, r, sess, "/monkey"+fmt.Sprintf("%v", i)) } token := TokenWithPath(w, r, sess, "/monkey") if token != sess.Values[TokenName].(StringMap)["/monkey"] { t.Errorf("Tokens do not match: expected %v, got %v", token, sess.Values[TokenName]) } }
func TestToken(t *testing.T) { var cookieName = "test" TokenName = "foo" // Create a cookiestore store := sessions.NewCookieStore([]byte("secret-key")) // Create the recorder w := httptest.NewRecorder() // Create the request r := fakeGet() // Get the session sess, err := store.Get(r, cookieName) if err != nil { t.Fatalf("Error getting session: %v", err) } token := Token(w, r, sess) if token != sess.Values[TokenName].(StringMap)["/"] { t.Errorf("Tokens do not match: expected %v, got %v", sess.Values[TokenName], token) } // Reset the token name TokenName = "token" }
func TestMatchRefererFail(t *testing.T) { var cookieName = "test" // Create a cookiestore store := sessions.NewCookieStore([]byte("secret-key")) // Create the form token := "123456" form := url.Values{} form.Set(TokenName, token) // Create the POST request req, err := http.NewRequest("POST", "http://localhost/login", bytes.NewBufferString(form.Encode())) if err != nil { panic(err) } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") // Pretend the page URL is /loginform, but the referrer is not set //req.Header.Set("Referer", "http://localhost/loginform") // Get the session sess, err := store.Get(req, cookieName) if err != nil { t.Fatalf("Error getting session: %v", err) } // Set the values in the session manually sess.Values[TokenName] = make(StringMap) sess.Values[TokenName].(StringMap)["/loginform"] = "123456" if ok := match(req, sess, true); ok { t.Error("Tokens should not match") } }
func TestMatchUniqueToken(t *testing.T) { var cookieName = "test" // Create a cookiestore store := sessions.NewCookieStore([]byte("secret-key")) // Create the recorder w := httptest.NewRecorder() // Create the handler h := New(http.HandlerFunc(successHandler), store, cookieName) // Use unique token per page SingleToken = false // Create the form token := "123456" form := url.Values{} form.Set(TokenName, token) // Create the POST request req, err := http.NewRequest("POST", "http://localhost/test", bytes.NewBufferString(form.Encode())) if err != nil { panic(err) } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") // Get the session sess, err := store.Get(req, cookieName) if err != nil { t.Fatalf("Error getting session: %v", err) } // Set the values in the session manually sess.Values[TokenName] = make(StringMap) sess.Values[TokenName].(StringMap)["/"] = "123456" // Run the page h.ServeHTTP(w, req) if w.Code == 200 { t.Errorf("The request should have failed, but it didn't. Instead, the code was %d", w.Code) } }
func TestCSRFJSON(t *testing.T) { var cookieName = "test" // Create a cookiestore store := sessions.NewCookieStore([]byte("secret-key")) // Create the recorder w := httptest.NewRecorder() // Create the handler h := New(http.HandlerFunc(successHandler), store, cookieName) // Create the form token := "123456" form := url.Values{} form.Set(TokenName, token) jsonValue := `{"token": "` + token + `"}` // Create the POST request req, err := http.NewRequest("POST", "http://localhost/", bytes.NewBufferString(jsonValue)) if err != nil { panic(err) } req.Header.Set("Content-Type", "application/json") // Get the session sess, err := store.Get(req, cookieName) if err != nil { t.Fatalf("Error getting session: %v", err) } // Set the values in the session manually sess.Values[TokenName] = make(StringMap) sess.Values[TokenName].(StringMap)["/"] = "123456" // Run the page h.ServeHTTP(w, req) if w.Code != 200 { t.Errorf("The request should have succeeded, but it didn't. Instead, the code was %d", w.Code) } }
func TestIsExempt(t *testing.T) { var cookieName = "test" // Create a cookiestore store := sessions.NewCookieStore([]byte("secret-key")) // Create the recorder w := httptest.NewRecorder() // Create the handler h := New(http.HandlerFunc(successHandler), store, cookieName) h.ExcludeRegexPaths([]string{"/skip(.*)"}) // Create the form token := "123456" form := url.Values{} form.Set(TokenName, token) // Create the POST request req, err := http.NewRequest("POST", "http://localhost/skip", bytes.NewBufferString(form.Encode())) if err != nil { panic(err) } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") // Get the session sess, err := store.Get(req, cookieName) if err != nil { t.Fatalf("Error getting session: %v", err) } // Set the values in the session manually sess.Values[TokenName] = make(StringMap) sess.Values[TokenName].(StringMap)["/"] = "123456ffffff" // Run the page h.ServeHTTP(w, req) if w.Code != 200 { t.Errorf("The request should have been successful, but it wasn't. Instead, the code was %d", w.Code) } }
func TestDontClearAfterUsage(t *testing.T) { var cookieName = "test" // Create a cookiestore store := sessions.NewCookieStore([]byte("secret-key")) // Create the recorder w := httptest.NewRecorder() // Create the handler h := New(http.HandlerFunc(successHandler), store, cookieName) h.ClearAfterUsage(false) // Create the form token := "123456" form := url.Values{} form.Set(TokenName, token) // Create the POST request req, err := http.NewRequest("POST", "http://localhost/", bytes.NewBufferString(form.Encode())) if err != nil { panic(err) } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") // Get the session sess, err := store.Get(req, cookieName) if err != nil { t.Fatalf("Error getting session: %v", err) } // Set the values in the session manually sess.Values[TokenName] = make(StringMap) sess.Values[TokenName].(StringMap)["/"] = "123456ffffff" // Run the page h.ServeHTTP(w, req) if _, ok := sess.Values[TokenName].(StringMap)["/"]; !ok { t.Error("The token should not have been deleted.") } }
func TestUniqueTokenPerPage(t *testing.T) { var cookieName = "test" // Create a cookiestore store := sessions.NewCookieStore([]byte("secret-key")) // Create the recorder w := httptest.NewRecorder() // Use unique token per page SingleToken = false // Create the GET request req, err := http.NewRequest("GET", "http://localhost/test1", nil) if err != nil { panic(err) } // Get the session sess, err := store.Get(req, cookieName) if err != nil { t.Fatalf("Error getting session: %v", err) } token1 := Token(w, req, sess) // Create the GET request req2, err := http.NewRequest("GET", "http://localhost/test2", nil) if err != nil { panic(err) } token2 := Token(w, req2, sess) if token1 == token2 { t.Error("Tokens should not match") } }
func TestSingleTokenPerSession(t *testing.T) { var cookieName = "test" // Create a cookiestore store := sessions.NewCookieStore([]byte("secret-key")) // Create the recorder w := httptest.NewRecorder() // Use single token SingleToken = true // Create the GET request req, err := http.NewRequest("GET", "http://localhost/test1", nil) if err != nil { panic(err) } // Get the session sess, err := store.Get(req, cookieName) if err != nil { t.Fatalf("Error getting session: %v", err) } token1 := Token(w, req, sess) // Create the GET request req2, err := http.NewRequest("GET", "http://localhost/test2", nil) if err != nil { panic(err) } token2 := Token(w, req2, sess) if token1 != token2 { t.Errorf("Tokens should match: expected %v, got %v", token1, token2) } }
func TestCSRFMissingTokenJSONNoPayload(t *testing.T) { var cookieName = "test" // Create a cookiestore store := sessions.NewCookieStore([]byte("secret-key")) // Create the recorder w := httptest.NewRecorder() // Create the handler h := New(http.HandlerFunc(successHandler), store, cookieName) // Create the POST request with no token req, err := http.NewRequest("POST", "http://localhost/", nil) if err != nil { panic(err) } req.Header.Set("Content-Type", "application/json") // Get the session sess, err := store.Get(req, cookieName) if err != nil { t.Fatalf("Error getting session: %v", err) } // Set the values in the session manually sess.Values[TokenName] = make(StringMap) // Run the page h.ServeHTTP(w, req) if w.Code == 200 { t.Errorf("The request should have failed, but it didn't. Instead, the code was %d", w.Code) } }