SIGN IN SIGN UP

fix(server): preserve custom iframe allowlists in frame headers (#6232)

* Preserve explicit iframe allowlists when hardening frame headers

The clickjacking fix correctly added frame-ancestors controls, but custom allowlists still emitted X-Frame-Options: DENY. This keeps SAMEORIGIN for 'self' and DENY for 'none', while letting explicit allowlists rely on CSP alone so supported embeds continue to work.

Constraint: Legacy X-Frame-Options cannot express arbitrary allowlists

Rejected: Keep DENY for all non-self values | breaks documented IFRAME_ORIGINS allowlists

Confidence: high

Scope-risk: narrow

Reversibility: clean

Directive: Keep CSP as the source of truth for custom iframe allowlists; do not reintroduce contradictory XFO headers

Tested: Added unit coverage for wildcard, self, none, and custom allowlists; local header reproduction for custom origin

Not-tested: Full browser iframe E2E across legacy browsers

* Avoid malformed iframe CSP values while removing per-request header recomputation

Gemini's review pointed out two low-risk improvements that strengthen the
existing iframe allowlist fix without changing its intent: normalize away empty
CSV tokens before building frame-ancestors, and compute the static header set
once during app startup instead of rebuilding it on every request.

Constraint: IFRAME_ORIGINS is startup configuration, not a dynamic per-request input
Rejected: Larger header-construction refactor | not necessary to address the concrete review feedback
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep CSP token normalization aligned with explicit allowlists so empty CSV segments never leak into frame-ancestors
Tested: pnpm --dir packages/server test -- src/utils/XSS.test.ts --runInBand
Not-tested: Full browser iframe embed verification against a running server

---------

Co-authored-by: yau-wd <yau.ong@workday.com>
J
Junghwan committed
1e21e61dad441de9f61bf22c6cc33ae4e1684d58
Parent: 3542a04
Committed by GitHub <noreply@github.com> on 4/21/2026, 8:31:13 AM