fix(web): gate /docs, /redoc, /openapi.json behind login
FastAPI auto-registers these with no auth of its own -- every other data route is individually wrapped in Depends(require_user), but these three are wired up internally by the FastAPI() constructor and were never covered by that. Confirmed live: all three returned 200 with zero session, handing anyone who could reach the port a full map of every route -- VM remove, cache purge, template delete, service control included -- without logging in. Disabled FastAPI's built-in docs_url/redoc_url/openapi_url and re-added all three as ordinary routes behind the same require_user dependency every other route uses. Verified against the live deployment: all three now 303 to /login instead of 200.
This commit is contained in:
@@ -152,6 +152,12 @@ reinstalls the `[web]` extra and restarts the service in one step (steps
|
||||
address while `[web.oidc]` is absent — an unauthenticated dashboard that
|
||||
can destroy VMs and purge caches must never be reachable from the LAN.
|
||||
Configure `[web.oidc]` first, or bind `127.0.0.1`.
|
||||
- **`/docs`, `/redoc`, `/openapi.json` are gated behind login too.** FastAPI
|
||||
auto-registers these with no auth of their own; the app disables its
|
||||
built-in ones (`docs_url=None` etc.) and re-adds them behind
|
||||
`require_user`, same as every data route — otherwise anyone who can reach
|
||||
the port gets a full map of every route (including every destructive one)
|
||||
with no session needed.
|
||||
- Every mutating route (VM remove/cleanup, cache purge, template backup,
|
||||
template delete, backup delete) is behind a synchronizer-token CSRF check
|
||||
and a two-step confirm gate (a preview/dry-run, then an explicit "Confirm"
|
||||
|
||||
Reference in New Issue
Block a user