Skip to content

Commit

Permalink
Fix louketo#409 - fixed size calculation of chunked cookies
Browse files Browse the repository at this point in the history
  • Loading branch information
jangaraj authored and Bruno Oliveira da Silva committed Dec 12, 2018
1 parent 5490863 commit 07db24b
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 16 deletions.
48 changes: 32 additions & 16 deletions cookies.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,42 +47,58 @@ func (r *oauthProxy) dropCookie(w http.ResponseWriter, host, name, value string,
http.SetCookie(w, cookie)
}

// maxCookieChunkSize calculates max cookie chunk size, which can be used for cookie value
func (r *oauthProxy) getMaxCookieChunkLength(req *http.Request, cookieName string) int {
maxCookieChunkLength := 4069 - len(cookieName)
if r.config.CookieDomain != "" {
maxCookieChunkLength = maxCookieChunkLength - len(r.config.CookieDomain)
} else {
maxCookieChunkLength = maxCookieChunkLength - len(strings.Split(req.Host, ":")[0])
}
if r.config.HTTPOnlyCookie {
maxCookieChunkLength = maxCookieChunkLength - len("HttpOnly; ")
}
if !r.config.EnableSessionCookies {
maxCookieChunkLength = maxCookieChunkLength - len("Expires=Mon, 02 Jan 2006 03:04:05 MST; ")
}
if r.config.SecureCookie {
maxCookieChunkLength = maxCookieChunkLength - len("Secure")
}
return maxCookieChunkLength
}

// dropAccessTokenCookie drops a access token cookie into the response
func (r *oauthProxy) dropAccessTokenCookie(req *http.Request, w http.ResponseWriter, value string, duration time.Duration) {
// also cookie name is included in the cookie length; cookie name suffix "-xxx"
maxCookieLength := 4089 - len(r.config.CookieAccessName)

if len(value) <= maxCookieLength {
maxCookieChunkLength := r.getMaxCookieChunkLength(req, r.config.CookieAccessName)
if len(value) <= maxCookieChunkLength {
r.dropCookie(w, req.Host, r.config.CookieAccessName, value, duration)
} else {
// write divided cookies because payload is too long for single cookie
r.dropCookie(w, req.Host, r.config.CookieAccessName, value[0:maxCookieLength], duration)
for i := maxCookieLength; i < len(value); i += maxCookieLength {
end := i + maxCookieLength
r.dropCookie(w, req.Host, r.config.CookieAccessName, value[0:maxCookieChunkLength], duration)
for i := maxCookieChunkLength; i < len(value); i += maxCookieChunkLength {
end := i + maxCookieChunkLength
if end > len(value) {
end = len(value)
}
r.dropCookie(w, req.Host, r.config.CookieAccessName+"-"+strconv.Itoa(i/maxCookieLength), value[i:end], duration)
r.dropCookie(w, req.Host, r.config.CookieAccessName+"-"+strconv.Itoa(i/maxCookieChunkLength), value[i:end], duration)
}
}
}

// dropRefreshTokenCookie drops a refresh token cookie into the response
func (r *oauthProxy) dropRefreshTokenCookie(req *http.Request, w http.ResponseWriter, value string, duration time.Duration) {
// also cookie name is included in the cookie length; cookie name suffix "-xxx"
maxCookieLength := 4089 - len(r.config.CookieRefreshName)

if len(value) <= maxCookieLength {
maxCookieChunkLength := r.getMaxCookieChunkLength(req, r.config.CookieRefreshName)
if len(value) <= maxCookieChunkLength {
r.dropCookie(w, req.Host, r.config.CookieRefreshName, value, duration)
} else {
// write divided cookies because payload is too long for single cookie
r.dropCookie(w, req.Host, r.config.CookieRefreshName, value[0:maxCookieLength], duration)
for i := maxCookieLength; i < len(value); i += maxCookieLength {
end := i + maxCookieLength
r.dropCookie(w, req.Host, r.config.CookieRefreshName, value[0:maxCookieChunkLength], duration)
for i := maxCookieChunkLength; i < len(value); i += maxCookieChunkLength {
end := i + maxCookieChunkLength
if end > len(value) {
end = len(value)
}
r.dropCookie(w, req.Host, r.config.CookieRefreshName+"-"+strconv.Itoa(i/maxCookieLength), value[i:end], duration)
r.dropCookie(w, req.Host, r.config.CookieRefreshName+"-"+strconv.Itoa(i/maxCookieChunkLength), value[i:end], duration)
}
}
}
Expand Down
19 changes: 19 additions & 0 deletions cookies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,22 @@ func TestClearAllCookies(t *testing.T) {
"kc-access=; Path=/; Domain=127.0.0.1; Expires=",
"we have not cleared the, headers: %v", resp.Header())
}

func TestGetMaxCookieChunkLength(t *testing.T) {
p, _, _ := newTestProxyService(nil)
req := newFakeHTTPRequest("GET", "/admin")

p.config.HTTPOnlyCookie = true
p.config.EnableSessionCookies = true
p.config.SecureCookie = true
p.config.CookieDomain = "1234567890"
assert.Equal(t, p.getMaxCookieChunkLength(req, "1234567890"), 4033,
"cookie chunk calculation is not correct")

p.config.HTTPOnlyCookie = false
p.config.EnableSessionCookies = false
p.config.SecureCookie = false
p.config.CookieDomain = ""
assert.Equal(t, p.getMaxCookieChunkLength(req, ""), 4021,
"cookie chunk calculation is not correct")
}

0 comments on commit 07db24b

Please sign in to comment.