1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2025-08-08 22:46:33 +02:00

Add configuration for cookie 'SameSite' value.

Values of 'lax' and 'strict' can improve and mitigate
some categories of cross-site traffic tampering.

Given that the nature of this proxy is often to proxy
private tools, this is useful to take advantage of.

See: https://www.owasp.org/index.php/SameSite
This commit is contained in:
Paul Groudas
2019-12-16 13:10:04 -05:00
parent 90f8117fba
commit 5d0827a028
8 changed files with 45 additions and 6 deletions

View File

@ -12,4 +12,5 @@ type CookieOptions struct {
CookieRefresh time.Duration `flag:"cookie-refresh" cfg:"cookie_refresh" env:"OAUTH2_PROXY_COOKIE_REFRESH"`
CookieSecure bool `flag:"cookie-secure" cfg:"cookie_secure" env:"OAUTH2_PROXY_COOKIE_SECURE"`
CookieHTTPOnly bool `flag:"cookie-httponly" cfg:"cookie_httponly" env:"OAUTH2_PROXY_COOKIE_HTTPONLY"`
CookieSameSite string `flag:"cookie-samesite" cfg:"cookie_samesite" env:"OAUTH2_PROXY_COOKIE_SAMESITE"`
}

View File

@ -1,6 +1,7 @@
package cookies
import (
"fmt"
"net"
"net/http"
"strings"
@ -12,7 +13,7 @@ import (
// MakeCookie constructs a cookie from the given parameters,
// discovering the domain from the request if not specified.
func MakeCookie(req *http.Request, name string, value string, path string, domain string, httpOnly bool, secure bool, expiration time.Duration, now time.Time) *http.Cookie {
func MakeCookie(req *http.Request, name string, value string, path string, domain string, httpOnly bool, secure bool, expiration time.Duration, now time.Time, sameSite http.SameSite) *http.Cookie {
if domain != "" {
host := req.Host
if h, _, err := net.SplitHostPort(host); err == nil {
@ -31,11 +32,28 @@ func MakeCookie(req *http.Request, name string, value string, path string, domai
HttpOnly: httpOnly,
Secure: secure,
Expires: now.Add(expiration),
SameSite: sameSite,
}
}
// MakeCookieFromOptions constructs a cookie based on the given *options.CookieOptions,
// value and creation time
func MakeCookieFromOptions(req *http.Request, name string, value string, opts *options.CookieOptions, expiration time.Duration, now time.Time) *http.Cookie {
return MakeCookie(req, name, value, opts.CookiePath, opts.CookieDomain, opts.CookieHTTPOnly, opts.CookieSecure, expiration, now)
return MakeCookie(req, name, value, opts.CookiePath, opts.CookieDomain, opts.CookieHTTPOnly, opts.CookieSecure, expiration, now, ParseSameSite(opts.CookieSameSite))
}
// Parse a valid http.SameSite value from a user supplied string for use of making cookies.
func ParseSameSite(v string) http.SameSite {
switch v {
case "lax":
return http.SameSiteLaxMode
case "strict":
return http.SameSiteStrictMode
case "none":
return http.SameSiteNoneMode
case "":
return http.SameSiteDefaultMode
default:
panic(fmt.Sprintf("Invalid value for SameSite: %s", v))
}
}

View File

@ -15,7 +15,7 @@ import (
. "github.com/onsi/gomega"
"github.com/pusher/oauth2_proxy/pkg/apis/options"
sessionsapi "github.com/pusher/oauth2_proxy/pkg/apis/sessions"
"github.com/pusher/oauth2_proxy/pkg/cookies"
cookiesapi "github.com/pusher/oauth2_proxy/pkg/cookies"
"github.com/pusher/oauth2_proxy/pkg/encryption"
"github.com/pusher/oauth2_proxy/pkg/sessions"
sessionscookie "github.com/pusher/oauth2_proxy/pkg/sessions/cookie"
@ -79,6 +79,12 @@ var _ = Describe("NewSessionStore", func() {
}
})
It("have the correct SameSite set", func() {
for _, cookie := range cookies {
Expect(cookie.SameSite).To(Equal(cookiesapi.ParseSameSite(cookieOpts.CookieSameSite)))
}
})
It("have a signature timestamp matching session.CreatedAt", func() {
for _, cookie := range cookies {
if cookie.Value != "" {
@ -159,7 +165,7 @@ var _ = Describe("NewSessionStore", func() {
By("Using a valid cookie with a different providers session encoding")
broken := "BrokenSessionFromADifferentSessionImplementation"
value := encryption.SignedValue(cookieOpts.CookieSecret, cookieOpts.CookieName, broken, time.Now())
cookie := cookies.MakeCookieFromOptions(request, cookieOpts.CookieName, value, cookieOpts, cookieOpts.CookieExpire, time.Now())
cookie := cookiesapi.MakeCookieFromOptions(request, cookieOpts.CookieName, value, cookieOpts, cookieOpts.CookieExpire, time.Now())
request.AddCookie(cookie)
err := ss.Save(response, request, session)
@ -338,6 +344,7 @@ var _ = Describe("NewSessionStore", func() {
CookieSecure: false,
CookieHTTPOnly: false,
CookieDomain: "example.com",
CookieSameSite: "strict",
}
var err error
@ -379,6 +386,7 @@ var _ = Describe("NewSessionStore", func() {
CookieRefresh: time.Duration(1) * time.Hour,
CookieSecure: true,
CookieHTTPOnly: true,
CookieSameSite: "",
}
session = &sessionsapi.SessionState{