fix(auth): give the OAuth popup a nonce CSP so its script runs #479
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/PMS-691-oauth-popup-csp-nonce"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The global CSP in
src/utils/security_headers.rssets noscript-src, so it falls back todefault-src 'none'and the browser blocks the inline script in the Google OAuth callback page. That script is the entire function of the page: itpostMessages the payload to the SPA opener and closes the popup, and the tokens exist nowhere else in the response, so sign-in completed server-side and the result was then discarded with the popup left open on "You can close this window."google_login::callback_responsenow mints a fresh 128-bit base64url nonce per request, emits it as<script nonce="...">, and sets the response's owncontent-security-policywithscript-src 'nonce-<value>'and no'unsafe-inline'. Nonce over hash because the script body is interpolated per request, so its hash changes every call. The global policy is unchanged, so the JSON API and thenot_a_frontendfallback keepdefault-src 'none'with no script-src at all.The middleware itself needed one fix for that to hold: it runs after the handler and used
insert, which clobbered a handler-set header rather than deferring to it as its doc comment claimed. It now usesentry(...).or_insert(...), so the handler wins and the middleware only fills in what is absent.Tests: the callback CSP nonce is parsed out of the header and asserted equal to the
<script>tag's nonce and free of'unsafe-inline'; a global-CSP test asserts noscript-srcand no nonce on any other route; and a router test asserts a handler-set CSP survives the middleware while the rest of the header set is still applied.#PMS-691