blob: 3c3eed7b4ff0e6d810f6e2b78cee0068767be58a [file] [log] [blame]
Jiri Simsad7616c92015-03-24 23:44:30 -07001// Copyright 2015 The Vanadium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Jiri Simsa5293dcb2014-05-10 09:56:38 -07005package util
6
7import (
Ankur8eabfa32014-11-04 11:09:01 -08008 "fmt"
Jiri Simsa5293dcb2014-05-10 09:56:38 -07009 "net/http"
10 "net/http/httptest"
11 "strings"
12 "testing"
13)
14
Suharsh Sivakumar44300662014-09-23 11:35:06 -070015const (
16 cookieName = "VeyronCSRFTestCookie"
17 failCookieName = "FailCookieName"
18)
19
Jiri Simsa5293dcb2014-05-10 09:56:38 -070020func TestCSRFTokenWithoutCookie(t *testing.T) {
21 r := newRequest()
Suharsh Sivakumar44300662014-09-23 11:35:06 -070022 c, err := NewCSRFCop()
23 if err != nil {
Suharsh Sivakumard308c7e2014-10-03 12:46:50 -070024 t.Fatalf("NewCSRFCop failed: %v", err)
Suharsh Sivakumar44300662014-09-23 11:35:06 -070025 }
Jiri Simsa5293dcb2014-05-10 09:56:38 -070026 w := httptest.NewRecorder()
Suharsh Sivakumar44300662014-09-23 11:35:06 -070027 tok, err := c.NewToken(w, r, cookieName, nil)
Jiri Simsa5293dcb2014-05-10 09:56:38 -070028 if err != nil {
29 t.Errorf("NewToken failed: %v", err)
30 }
Ankur8eabfa32014-11-04 11:09:01 -080031 cookie, err := cookieVal(w, cookieName)
32 if err != nil {
33 t.Error(err)
34 }
Jiri Simsa5293dcb2014-05-10 09:56:38 -070035 if len(cookie) == 0 {
36 t.Errorf("Cookie should have been set. Request: [%v], Response: [%v]", r, w)
37 }
38 // Cookie needs to be present for validation
39 r.AddCookie(&http.Cookie{Name: cookieName, Value: cookie})
Suharsh Sivakumar44300662014-09-23 11:35:06 -070040 if err := c.ValidateToken(tok, r, cookieName, nil); err != nil {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070041 t.Error("CSRF token failed validation:", err)
42 }
Suharsh Sivakumar44300662014-09-23 11:35:06 -070043
44 w = httptest.NewRecorder()
45 if _, err = c.MaybeSetCookie(w, r, failCookieName); err != nil {
46 t.Error("failed to create cookie: ", err)
47 }
Ankur8eabfa32014-11-04 11:09:01 -080048 cookie, err = cookieVal(w, failCookieName)
49 if err != nil {
50 t.Error(err)
51 }
Suharsh Sivakumar44300662014-09-23 11:35:06 -070052 if len(cookie) == 0 {
53 t.Errorf("Cookie should have been set. Request: [%v], Response: [%v]", r, w)
54 }
55
56 if err := c.ValidateToken(tok, r, failCookieName, nil); err == nil {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070057 t.Error("CSRF token should have failed validation")
58 }
59}
60
61func TestCSRFTokenWithCookie(t *testing.T) {
62 r := newRequest()
Suharsh Sivakumar44300662014-09-23 11:35:06 -070063 c, err := NewCSRFCop()
64 if err != nil {
Suharsh Sivakumard308c7e2014-10-03 12:46:50 -070065 t.Fatalf("NewCSRFCop failed: %v", err)
Suharsh Sivakumar44300662014-09-23 11:35:06 -070066 }
Jiri Simsa5293dcb2014-05-10 09:56:38 -070067 w := httptest.NewRecorder()
68 r.AddCookie(&http.Cookie{Name: cookieName, Value: "u776AC7hf794pTtGVlO50w=="})
Suharsh Sivakumar44300662014-09-23 11:35:06 -070069 tok, err := c.NewToken(w, r, cookieName, nil)
Jiri Simsa5293dcb2014-05-10 09:56:38 -070070 if err != nil {
71 t.Errorf("NewToken failed: %v", err)
72 }
Ankur8eabfa32014-11-04 11:09:01 -080073 cookie, err := cookieVal(w, cookieName)
74 if err != nil {
75 t.Error(err)
76 }
77 if len(cookie) > 0 {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070078 t.Errorf("Cookie should not be set when it is already present. Request: [%v], Response: [%v]", r, w)
79 }
Suharsh Sivakumar44300662014-09-23 11:35:06 -070080 if err := c.ValidateToken(tok, r, cookieName, nil); err != nil {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070081 t.Error("CSRF token failed validation:", err)
82 }
Suharsh Sivakumar44300662014-09-23 11:35:06 -070083
84 r.AddCookie(&http.Cookie{Name: failCookieName, Value: "u864AC7gf794pTtCAlO40w=="})
85 if err := c.ValidateToken(tok, r, failCookieName, nil); err == nil {
86 t.Error("CSRF token should have failed validation")
87 }
88}
89
90func TestCSRFTokenWithData(t *testing.T) {
91 r := newRequest()
92 c, err := NewCSRFCop()
93 if err != nil {
Suharsh Sivakumard308c7e2014-10-03 12:46:50 -070094 t.Fatalf("NewCSRFCop failed: %v", err)
Suharsh Sivakumar44300662014-09-23 11:35:06 -070095 }
96 w := httptest.NewRecorder()
97 r.AddCookie(&http.Cookie{Name: cookieName, Value: "u776AC7hf794pTtGVlO50w=="})
98 tok, err := c.NewToken(w, r, cookieName, 1)
99 if err != nil {
100 t.Errorf("NewToken failed: %v", err)
101 }
Ankur8eabfa32014-11-04 11:09:01 -0800102 cookie, err := cookieVal(w, cookieName)
103 if err != nil {
104 t.Error(err)
105 }
106 if len(cookie) > 0 {
Suharsh Sivakumar44300662014-09-23 11:35:06 -0700107 t.Errorf("Cookie should not be set when it is already present. Request: [%v], Response: [%v]", r, w)
108 }
109 var got int
110 if err := c.ValidateToken(tok, r, cookieName, &got); err != nil {
111 t.Error("CSRF token failed validation:", err)
112 }
113 if want := 1; got != want {
114 t.Errorf("Got %v, want %v", got, want)
115 }
116
117 r.AddCookie(&http.Cookie{Name: failCookieName, Value: "u864AC7gf794pTtCAlO40w=="})
118 if err := c.ValidateToken(tok, r, failCookieName, &got); err == nil {
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700119 t.Error("CSRF token should have failed validation")
120 }
121}
122
Ankur8eabfa32014-11-04 11:09:01 -0800123func cookieVal(w *httptest.ResponseRecorder, cookieName string) (string, error) {
124 cookie := w.Header().Get("Set-Cookie")
125 if len(cookie) == 0 {
126 return "", nil
127 }
128 var (
129 val string
130 httpOnly, secure bool
131 )
132 for _, part := range strings.Split(cookie, "; ") {
133 switch {
134 case strings.HasPrefix(part, cookieName):
135 val = strings.TrimPrefix(part, cookieName+"=")
136 case part == "HttpOnly":
137 httpOnly = true
138 case part == "Secure":
139 secure = true
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700140 }
141 }
Ankur8eabfa32014-11-04 11:09:01 -0800142 if !httpOnly {
143 return "", fmt.Errorf("cookie for name %v is not HttpOnly", cookieName)
144 }
145 if !secure {
146 return "", fmt.Errorf("cookie for name %v is not Secure", cookieName)
147 }
148 return val, nil
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700149}