From 3163f46f40528fa8839c30a14dd8fb3ca043d3ca Mon Sep 17 00:00:00 2001 From: Alan Hazelton Date: Mon, 6 Apr 2026 14:20:32 -0400 Subject: [PATCH] update zrok_session cookie to work with XHR --- endpoints/dynamicProxy/http.go | 5 +++++ endpoints/oauthCookies.go | 14 +++++++------- endpoints/publicProxy/http.go | 5 +++++ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/endpoints/dynamicProxy/http.go b/endpoints/dynamicProxy/http.go index a055e1bb..f5583430 100644 --- a/endpoints/dynamicProxy/http.go +++ b/endpoints/dynamicProxy/http.go @@ -117,6 +117,11 @@ func newServiceProxy(cfg *config, ctx ziti.Context, mappings *mappings) (*httput req.Header.Set("X-Proxy", "zrok") } proxy.ModifyResponse = func(resp *http.Response) error { + origin := resp.Request.Header.Get("Origin") + // CORS will block the zrok_session cookie for XHR requests if the server sends responds with * + if origin != "" && resp.Header.Get("Access-Control-Allow-Origin") == "*" { + resp.Header.Set("Access-Control-Allow-Origin", origin) + } return nil } proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) { diff --git a/endpoints/oauthCookies.go b/endpoints/oauthCookies.go index 54b7a5e9..485a091c 100644 --- a/endpoints/oauthCookies.go +++ b/endpoints/oauthCookies.go @@ -173,13 +173,13 @@ func SetSessionCookie(w http.ResponseWriter, cookieName string, tokenValue strin // common cookie attributes cookieAttrs := &http.Cookie{ - MaxAge: int(cfg.GetSessionLifetime().Seconds()), - Domain: cfg.GetCookieDomain(), - Path: "/", - Expires: time.Now().Add(cfg.GetSessionLifetime()), - // Secure: true, // pending server tls feature https://github.com/openziti/zrok/issues/24 - HttpOnly: true, // enabled because zrok frontend is the only intended consumer of this cookie, not client-side scripts - SameSite: http.SameSiteLaxMode, // explicitly set to the default Lax mode which allows the zrok share to be navigated to from another site and receive the cookie + MaxAge: int(cfg.GetSessionLifetime().Seconds()), + Domain: cfg.GetCookieDomain(), + Path: "/", + Expires: time.Now().Add(cfg.GetSessionLifetime()), + Secure: true, + HttpOnly: true, // enabled because zrok frontend is the only intended consumer of this cookie, not client-side scripts + SameSite: http.SameSiteNoneMode, // None required so cross-origin XHR/fetch requests with withCredentials include the cookie } // check if we need to stripe the cookie diff --git a/endpoints/publicProxy/http.go b/endpoints/publicProxy/http.go index 9d1ed072..6ac0d9e3 100644 --- a/endpoints/publicProxy/http.go +++ b/endpoints/publicProxy/http.go @@ -113,6 +113,11 @@ func newServiceProxy(cfg *Config, ctx ziti.Context) (*httputil.ReverseProxy, err req.Header.Set("X-Proxy", "zrok") } proxy.ModifyResponse = func(resp *http.Response) error { + origin := resp.Request.Header.Get("Origin") + // CORS will block the zrok_session cookie for XHR requests if the server sends responds with * + if origin != "" && resp.Header.Get("Access-Control-Allow-Origin") == "*" { + resp.Header.Set("Access-Control-Allow-Origin", origin) + } return nil } proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) {