From ec014867e718f0ca1fb87cd2dcaaab14d33101cd Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Fri, 7 Aug 2026 19:42:38 +0200 Subject: [PATCH] Send a `Content-Security-Policy` header on every response Each router gets the policy for the kind of route it serves, applied with `SetResponseHeaderLayer::if_not_present` so that a more specific inner router or handler wins: the SPA shell routes live inside the server-rendered `human_router` and set their own, the password registration page is the only one which trusts the captcha provider's origins, and the two Swagger UI pages are quarantined behind theirs inside the admin API router. The catch-all sits at the top level, next to `X-Content-Type-Options: nosniff` and the existing `X-Frame-Options: DENY`, so nothing can ship headerless by accident. That also gives the compat SSO redirect pages security headers, which they had none of. The 404 page is the one handler which sets its own: it is registered outside every router, so it would otherwise inherit a policy which blocks its own stylesheet. The upstream back-channel logout endpoint moves to `api_router`. It is called by the upstream provider rather than by a browser, and was only in the human router by accident, picking up a page policy, the `X-Frame-Options` header and the HTML error wrapper it has no use for. The `HttpResource` which mounts it changes from `human` to `oauth`. The SPA shell carries a temporary `style-src 'unsafe-inline'` concession for the `