Summary
The Content-Security-Policy is maintained in two places that can drift: a hand-written <meta http-equiv="Content-Security-Policy"> in frontend/index.html and the generated source of truth in frontend/src/csp/policy.ts (emitted to headers via scripts/generateCSP.ts).
Evidence
frontend/index.html contains a full connect-src/img-src CSP meta tag (its own comment warns it is a "development fallback only" and "do not edit by hand").
frontend/src/csp/policy.ts is the generated/header source of truth.
The two lists of allowed origins are maintained separately, so adding/removing an endpoint in one can silently diverge from the other.
Suggested fix
Generate the dev index.html meta tag from policy.ts (the same source as the header), or drop the static directive list in favor of a placeholder the build replaces, so there is a single source of truth for allowed origins.
Summary
The Content-Security-Policy is maintained in two places that can drift: a hand-written
<meta http-equiv="Content-Security-Policy">infrontend/index.htmland the generated source of truth infrontend/src/csp/policy.ts(emitted to headers viascripts/generateCSP.ts).Evidence
frontend/index.htmlcontains a fullconnect-src/img-srcCSP meta tag (its own comment warns it is a "development fallback only" and "do not edit by hand").frontend/src/csp/policy.tsis the generated/header source of truth.The two lists of allowed origins are maintained separately, so adding/removing an endpoint in one can silently diverge from the other.
Suggested fix
Generate the dev
index.htmlmeta tag frompolicy.ts(the same source as the header), or drop the static directive list in favor of a placeholder the build replaces, so there is a single source of truth for allowed origins.