fix(csp): bake exact generated-image R2 host into tenant img-src pin (#3128 follow-up) #3131
Reference in New Issue
Block a user
Delete Branch "fix/csp-img-src-pin-exact-r2-host"
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?
What
Follow-up to #3128. Drop the wildcard: make the tenant-UI CSP
img-srcemit the exact generated-image R2 host instead ofhttps://*.r2.cloudflarestorage.com.This PR wires the canvas BUILD-time pin (
NEXT_PUBLIC_IMAGE_GEN_R2_HOST). The Go RUNTIME pin (MOLECULE_IMAGE_GEN_R2_HOSTin the tenant container env) is wired in molecule-controlplane PRfix/csp-img-src-pin-exact-r2-host-runtime. Browsers enforce the intersection of both emitters, so both must carry the exact host.Exact host
Derived from the CP's own R2 config (bucket
molecule-workspace-data+ endpoint account-hashbfa4e604e168a938e565600b27e2828c). Verified against Infisical/shared/controlplanefor both prod and staging — they share the bucket + Cloudflare account, so a single baked value is correct (no cross-env mismatch). Image gen is enabled on prod; staging shares the same bucket/endpoint via the workspace-data fallback.Changes (img-src only — connect-src untouched)
workspace-server/Dockerfile.tenant:ARG+ENV NEXT_PUBLIC_IMAGE_GEN_R2_HOSTin the canvas-builder stage, beforenpm run build(Next.js inlinesNEXT_PUBLIC_*at build time)..gitea/workflows/publish-workspace-server-image.yml: pass--build-arg NEXT_PUBLIC_IMAGE_GEN_R2_HOST, sourced from theIMAGE_GEN_R2_HOSTrepo variable (config, not a secret) defaulting to the production-derived host.canvas/Dockerfile+publish-canvas-image.yml: same wiring for the standalone canvas image (docker-compose / self-host parity).workspace-server/internal/middleware/csp_imgsrc_build_wiring_test.go: guards that the build actually sets the pin (ARG+ENV present, set before build, CI passes the exact non-wildcard host).Deploy path
Merge → core CI
publish-workspace-server-image.ymlbuilds the combined platform-tenant image with the exact host baked into the canvas bundle →:latestpromoted on prod-green → a tenant redeploy pulls the new image → tenant UI emits the exact host.Verify (after deploy + tenant redeploy)
img-srcshows the exact host and no*.r2.cloudflarestorage.com.🤖 Generated with Claude Code
Reviewed: cosmetic finisher to the exact-host CSP tightening — removes the now-dead *.r2.cloudflarestorage.com wildcard from the canvas img-src literal (the ENFORCED exact-host pin already shipped via merged #890 on the Go side; browser enforces the intersection). img-src only; connect-src untouched. LGTM.
Reviewed: cosmetic finisher to the exact-host CSP tightening — removes the now-dead *.r2.cloudflarestorage.com wildcard from the canvas img-src literal (the ENFORCED exact-host pin already shipped via merged #890 on the Go side; browser enforces the intersection). img-src only; connect-src untouched. LGTM.