From 4fed8008cebece998a5e4f4b33673983ce9c7c43 Mon Sep 17 00:00:00 2001 From: Kenedy Torcatt Date: Tue, 14 Jul 2026 17:26:34 -0600 Subject: [PATCH] fix(sso): admin auth-redirect must not preempt an incoming cookie-less token handle_auth_redirect() kicks off an SSO round-trip for any wp-admin request that is not logged in and not on the main domain. When the request ALREADY carries a valid ?wu_sso_token= (the cookie-less flow that panel/iframe integrations use to open a subsite's customizer or admin), that kick-off fires BEFORE handle_cookie_less_sso_token() (init:4) can consume the token: the request is 302'd to the main /login/, which mints yet another token and sends the browser back - an infinite customize.php <-> /login/ loop (~2 rounds/sec in production access logs). Front-end URLs are unaffected (no kick-off there), which is why the bug only surfaces on wp-admin targets like the customizer. Real-world impact (kursopro.com, 2026-07-14): the site customizer opened through the panel was down for every subsite - the embedding UI just shows a generic error while the iframe loops. Fix: mirror the existing $sso_path short-circuit - when wu_sso_token is present in the current request, return true so the auth redirect is bypassed and the init:4 receiver consumes the token. Verified end-to-end in production: token -> 302 clean URL + auth cookies -> HTTP 200 customizer. --- inc/sso/class-sso.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/inc/sso/class-sso.php b/inc/sso/class-sso.php index 7e13884e..3861223b 100644 --- a/inc/sso/class-sso.php +++ b/inc/sso/class-sso.php @@ -390,6 +390,19 @@ public function handle_auth_redirect() { if ($this->input($sso_path) && $this->input($sso_path) !== 'done') { return true; } + /* + * A request that already carries a cookie-less SSO token must not kick + * off a new SSO round-trip: handle_cookie_less_sso_token() (init:4) is + * about to consume it and set the auth cookies. Without this + * short-circuit, wp-admin URLs like customize.php?wu_sso_token=... are + * redirected to the main /login/ BEFORE consumption, the main site mints + * yet another token and the browser loops forever between customize.php + * and /login/ (~2 rounds/sec observed in production access logs). This + * mirrors the $sso_path short-circuit right above. + */ + if ('' !== (string) $this->input('wu_sso_token', '')) { + return true; + } $should_skip_redirect = $this->get_isset($_COOKIE, 'wu_sso_denied', false);