a65a517d04
The PKCE payload is a flat 'provider=...;state=...;verifier=...;next=...' string. A raw ';' is a cookie-attribute terminator, so Python's http.cookies emits the value in RFC 6265 quoted form with each ';' escaped as the backslash-octal '\073'. Mainstream browsers echo that form back verbatim and Python parsers decode it — the browser round trip is fine. But '"' and '\' are outside the plain cookie-octet set, and non-Python hops that re-serialize the Cookie header reject the value and drop the cookie entirely: Go's net/http (Traefik middleware, Authentik outposts, other gateways) refuses any cookie value containing a backslash. The OIDC callback then 400s with "Missing PKCE state cookie" even though the browser sent the cookie. Field reproduction: support thread "Still unable to use Authentik for signin with traefik" — devtools showed the browser sending the intact quoted \073 cookie on /auth/callback while Hermes logged missing_pkce_cookie behind a Traefik+Authentik chain. Fix: URL-encode the whole payload in set_pkce_cookie (quote(payload, safe='') — ';' becomes '%3B') so the wire value contains only cookie-octets and no parser in the chain has anything to reject, and decode through a single shared inverse, cookies.parse_pkce_payload(), in BOTH readers: the OAuth /auth/callback and the native password-login path (routes.login_submit), whose broker/provider binding check would otherwise parse zero segments from the newly-encoded value and silently disable itself. Regression coverage: the wire-shape test pins the full cookie-octet set (the '"'/'\' assertions are the ones a Go-parser hop fails pre-fix), the round-trip tests drive the real /auth/login → /auth/callback path, and the next= test pins the exact post-login redirect byte shape. Native-flow broker assertions updated to decode through parse_pkce_payload instead of substring-matching the raw wire value. Salvaged from #84065 (rebased onto current main, which gained the SameSite=None PKCE attrs and the RFC 8252 native password flow since the PR branched): kept main's _pkce_attrs cookie shape, extended the fix to the login_submit reader the original PR predated, and reframed the rationale — browsers do NOT truncate at the first ';' (there is no literal ';' on the wire in the quoted form); the failing hop is a strict middlebox cookie parser. Closes #83832 Co-authored-by: Kailigithub <12250313+Kailigithub@users.noreply.github.com>