You've already forked oauth2-proxy
mirror of
https://github.com/oauth2-proxy/oauth2-proxy.git
synced 2025-08-08 22:46:33 +02:00
feat(cookie) csrf per request limit (#3134)
* Allow setting maximum number of csrf cookies, deleting the oldest if necessary * Add a test for multiple CSRF cookies to remove the old cookie * Add docs/changelog * If limit is <=0 do not clear Signed-off-by: test <bert@transtrend.com> * Better docs Co-authored-by: Jan Larwig <jan@larwig.com> * direct check of option value Co-authored-by: Jan Larwig <jan@larwig.com> * direct use of option value Co-authored-by: Jan Larwig <jan@larwig.com> * sort based on clock compare vs time compare Co-authored-by: Jan Larwig <jan@larwig.com> * clock.Clock does not implement Compare, fix csrf cookie extraction after rename Signed-off-by: Bert Helderman <bert@transtrend.com> * Linter fix * add method signature documentation and slight formatting Signed-off-by: Jan Larwig <jan@larwig.com> * fix: test case for csrf cookie limit and flag Signed-off-by: Jan Larwig <jan@larwig.com> --------- Signed-off-by: Bert Helderman <bert@transtrend.com> Signed-off-by: Jan Larwig <jan@larwig.com> Co-authored-by: test <bert@transtrend.com> Co-authored-by: bh-tt <71650427+bh-tt@users.noreply.github.com>
This commit is contained in:
@ -190,5 +190,84 @@ var _ = Describe("CSRF Cookie with non-fixed name Tests", func() {
|
||||
Expect(privateCSRF.cookieName()).To(ContainSubstring(cookieName))
|
||||
})
|
||||
})
|
||||
|
||||
Context("CSRF per request limit", func() {
|
||||
It("clears cookies based on the limit", func() {
|
||||
//needs to be now as pkg/encryption/utils.go uses time.Now()
|
||||
testNow := time.Now()
|
||||
cookieOpts.CSRFPerRequestLimit = 1
|
||||
|
||||
publicCSRF1, err := NewCSRF(cookieOpts, "verifier")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
privateCSRF1 := publicCSRF1.(*csrf)
|
||||
privateCSRF1.time.Set(testNow)
|
||||
|
||||
publicCSRF2, err := NewCSRF(cookieOpts, "verifier")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
privateCSRF2 := publicCSRF2.(*csrf)
|
||||
privateCSRF2.time.Set(testNow.Add(time.Minute))
|
||||
|
||||
publicCSRF3, err := NewCSRF(cookieOpts, "verifier")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
privateCSRF3 := publicCSRF3.(*csrf)
|
||||
privateCSRF3.time.Set(testNow.Add(time.Minute * 2))
|
||||
|
||||
cookies := []string{}
|
||||
for _, csrf := range []*csrf{privateCSRF1, privateCSRF2, privateCSRF3} {
|
||||
encoded, err := csrf.encodeCookie()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
cookie := MakeCookieFromOptions(
|
||||
req,
|
||||
csrf.cookieName(),
|
||||
encoded,
|
||||
csrf.cookieOpts,
|
||||
csrf.cookieOpts.CSRFExpire,
|
||||
)
|
||||
cookies = append(cookies, fmt.Sprintf("%v=%v", cookie.Name, cookie.Value))
|
||||
}
|
||||
|
||||
header := make(map[string][]string, 1)
|
||||
header["Cookie"] = cookies
|
||||
req = &http.Request{
|
||||
Method: http.MethodGet,
|
||||
Proto: "HTTP/1.1",
|
||||
Host: cookieDomain,
|
||||
|
||||
URL: &url.URL{
|
||||
Scheme: "https",
|
||||
Host: cookieDomain,
|
||||
Path: cookiePath,
|
||||
},
|
||||
Header: header,
|
||||
}
|
||||
|
||||
// when setting the limit to one csrf cookie but configuring three csrf cookies
|
||||
// then two cookies should be removed / set to expired on the response
|
||||
|
||||
// for this test case we have set all the cookies on a single request,
|
||||
// but in reality this will be multiple requests after another
|
||||
rw := httptest.NewRecorder()
|
||||
ClearExtraCsrfCookies(cookieOpts, rw, req)
|
||||
|
||||
clearedCookies := rw.Header()["Set-Cookie"]
|
||||
Expect(clearedCookies).To(HaveLen(2))
|
||||
Expect(clearedCookies[0]).To(Equal(
|
||||
fmt.Sprintf(
|
||||
"%s=; Path=%s; Domain=%s; Max-Age=0; HttpOnly; Secure",
|
||||
privateCSRF1.cookieName(),
|
||||
cookiePath,
|
||||
cookieDomain,
|
||||
),
|
||||
))
|
||||
Expect(clearedCookies[1]).To(Equal(
|
||||
fmt.Sprintf(
|
||||
"%s=; Path=%s; Domain=%s; Max-Age=0; HttpOnly; Secure",
|
||||
privateCSRF2.cookieName(),
|
||||
cookiePath,
|
||||
cookieDomain,
|
||||
),
|
||||
))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user