From 99bbcb34b6df8d20de9634b55280e2c940bf95de Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Thu, 26 Feb 2026 05:00:42 +0000 Subject: [PATCH] Add config option to bypass cookie checking on SSO callback. Signed-off-by: Jason Volk --- src/api/client/session/sso.rs | 34 +++++++++++++++++++--------------- src/core/config/mod.rs | 9 +++++++++ tuwunel-example.toml | 7 +++++++ 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/api/client/session/sso.rs b/src/api/client/session/sso.rs index 1c5dd0e4..a4c17da9 100644 --- a/src/api/client/session/sso.rs +++ b/src/api/client/session/sso.rs @@ -301,24 +301,28 @@ pub(crate) async fn sso_callback_route( return Err!(Request(Unauthorized("Authorization grant session has expired."))); } - let cookie = body - .cookie - .get(GRANT_SESSION_COOKIE) - .map(Cookie::value) - .map(serde_html_form::from_str::>) - .transpose()? - .ok_or_else(|| err!(Request(Unauthorized("Missing cookie {GRANT_SESSION_COOKIE:?}"))))?; + if provider.check_cookie { + let cookie = body + .cookie + .get(GRANT_SESSION_COOKIE) + .map(Cookie::value) + .map(serde_html_form::from_str::>) + .transpose()? + .ok_or_else(|| { + err!(Request(Unauthorized("Missing cookie {GRANT_SESSION_COOKIE:?}"))) + })?; - if cookie.client_id.as_ref() != client_id.as_str() { - return Err!(Request(Unauthorized("Client ID {client_id:?} cookie mismatch."))); - } + if cookie.client_id.as_ref() != client_id.as_str() { + return Err!(Request(Unauthorized("Client ID {client_id:?} cookie mismatch."))); + } - if Some(cookie.nonce.as_ref()) != session.cookie_nonce.as_deref() { - return Err!(Request(Unauthorized("Cookie nonce does not match session state."))); - } + if Some(cookie.nonce.as_ref()) != session.cookie_nonce.as_deref() { + return Err!(Request(Unauthorized("Cookie nonce does not match session state."))); + } - if cookie.state.as_ref() != sess_id { - return Err!(Request(Unauthorized("Session ID {sess_id:?} cookie mismatch."))); + if cookie.state.as_ref() != sess_id { + return Err!(Request(Unauthorized("Session ID {sess_id:?} cookie mismatch."))); + } } // Request access token. diff --git a/src/core/config/mod.rs b/src/core/config/mod.rs index 1345bd45..2c9e5965 100644 --- a/src/core/config/mod.rs +++ b/src/core/config/mod.rs @@ -2768,6 +2768,15 @@ pub struct IdentityProvider { /// default: 300 #[serde(default = "default_sso_grant_session_duration")] pub grant_session_duration: Option, + + /// Whether to check the redirect cookie during the callback. This is a + /// security feature and should remain enabled. This is available for + /// developers or deployments which cannot tolerate cookies and are willing + /// to tolerate the risks. + /// + /// default: true + #[serde(default = "true_fn")] + pub check_cookie: bool, } impl IdentityProvider { diff --git a/tuwunel-example.toml b/tuwunel-example.toml index 9749f4eb..f2c7d1ea 100644 --- a/tuwunel-example.toml +++ b/tuwunel-example.toml @@ -2378,6 +2378,13 @@ # #grant_session_duration = 300 +# Whether to check the redirect cookie during the callback. This is a +# security feature and should remain enabled. This is available for +# developers or deployments which cannot tolerate cookies and are willing +# to tolerate the risks. +# +#check_cookie = true + #[global.appservice.]