fix(iframe-embed): render iframe only after framable check (XFO-DENY fallback race)#17
Merged
Merged
Conversation
…NY fallback wins the race The server-side framable check (REQ-IFRAME-003) is async, but the iframe was rendered immediately in the 'loading' state. For an X-Frame-Options: DENY target the browser fires a 'load' event for its own 'refused to connect' page with a null contentDocument — indistinguishable from a successful cross-origin embed — so onLoad flipped the widget to 'ready' before the framable check resolved, and the check's 'state !== loading' guard then no-oped. Result: a permanently blank frame instead of the fallback card. Only render the iframe once the server confirms framing is permitted (framableConfirmed). The premature blocked-frame load can no longer fire. Caught live via Playwright (unit test passed because the mock resolves synchronously); adds a regression test asserting no iframe exists while the check is pending.
rubenvdlinde
requested review from
SudoThijn,
WilcoLouwerse,
bbrands02,
remko48 and
rjzondervan
as code owners
July 26, 2026 09:12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The iframe-embed widget's server-side framable check (REQ-IFRAME-003) is async, but the iframe was rendered immediately in the
loadingstate. For anX-Frame-Options: DENYtarget, the browser fires aloadevent for its own "refused to connect" page with a nullcontentDocument— indistinguishable from a successful cross-origin embed — soonLoadflipped the widget toreadybefore the framable check resolved. The check'sstate !== 'loading'guard then no-oped, leaving a permanently blank frame instead of the fallback card.This was invisible to unit tests (the mocked check resolves synchronously) and only surfaced under live async ordering.
Fix
Render the iframe only after the server confirms framing is permitted (
framableConfirmed). The premature blocked-frameloadcan no longer fire, so the framable check always wins.Verification
Follow-up to #16.