Skip to content

Fix iframe communication failure under Chrome strict-origin-isolation#901

Draft
MelvinBot wants to merge 2 commits intomainfrom
claude-fixIframeifyStrictOriginIsolation
Draft

Fix iframe communication failure under Chrome strict-origin-isolation#901
MelvinBot wants to merge 2 commits intomainfrom
claude-fixIframeifyStrictOriginIsolation

Conversation

@MelvinBot
Copy link
Copy Markdown

@MelvinBot MelvinBot commented Mar 12, 2026

When Chrome's strict-origin-isolation flag is enabled (or when document.domain setter is fully deprecated in future Chrome versions), the expensifyIframeify plugin fails silently because:

  1. document.domain = domainWithoutSubdomain throws a SecurityError
  2. window.parent.location.protocol/.hostname throws a SecurityError (cross-origin property access denied)
  3. iframeElement[0].contentWindow.location throws the same error

This causes any iframe communication between www.expensify.com and secure.expensify.com (e.g., the deposit-only bank account flow) to get stuck on a loading screen indefinitely, because postMessage is never called.

Changes:

  • Wrap the document.domain setter in a try/catch so it degrades gracefully when blocked
  • Wrap window.parent.location access in a try/catch; on failure, fall back to '*' as targetOrigin
  • Wrap contentWindow.location access in a try/catch; on failure, fall back to '*' as targetOrigin

Using '*' as the targetOrigin fallback is safe because the receiving side's handleWindowMessage independently validates event.origin against the allowedCommunications whitelist. The targetOrigin parameter only controls whether the browser delivers the message — it does not affect the origin validation on the receiving end.

In the normal case (no strict-origin-isolation), the try blocks succeed and behavior is identical to before. The fallbacks only activate when cross-origin access is blocked.

Fixed Issues

$ https://github.com/Expensify/Expensify/issues/606093

Tests

  • ESLint passes with no warnings (npx eslint lib/jquery.expensifyIframify.js --quiet)
  • All 418 existing unit tests pass (npm test)
  • No existing tests for jquery.expensifyIframify.js (browser-specific APIs like window.parent, document.domain, and iframes require a full browser environment)
  • Manual verification: Under normal conditions (no strict-origin-isolation), the try block succeeds on the first line and behavior is identical to the original code. The catch/fallback paths only execute when SecurityError is thrown.

QA

  1. With strict-origin-isolation enabled: Navigate to chrome://flags, enable strict-origin-isolation, restart Chrome. Go to Settings > Account > Wallet > Add deposit-only Bank account. Verify the Plaid flow loads and completes successfully instead of getting stuck on a loading screen.
  2. Without strict-origin-isolation (regression): With the flag disabled (default), repeat the same flow. Verify it still works identically to before — the try blocks should succeed and the fallback code should never execute.
  3. Test areas for regressions: Any flow that uses iframe communication between www.expensify.com and secure.expensify.com (bank account setup, payment card setup, Salesforce integration).

When Chrome's strict-origin-isolation flag is enabled, three operations
in the expensifyIframeify plugin throw SecurityError:

1. document.domain setter (blocked under origin isolation)
2. window.parent.location access (cross-origin property access denied)
3. contentWindow.location access (cross-origin property access denied)

This causes the deposit-only bank account flow (and any other iframe
communication between www.expensify.com and secure.expensify.com) to
get stuck on a loading screen indefinitely.

Changes:
- Wrap document.domain setter in try/catch so it degrades gracefully
- Add try/catch around window.parent.location access with fallback to
  inferring the parent origin from the allowedCommunications whitelist
- Add try/catch around contentWindow.location access with fallback to
  extracting the origin from the iframe's src attribute

Co-authored-by: Stephanie Elliott <stephanieelliott@users.noreply.github.com>
@MelvinBot MelvinBot requested a review from a team March 12, 2026 02:43
@github-actions
Copy link
Copy Markdown


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

Replace the allowedCommunications lookup and iframe src parsing
fallbacks with a simple '*' targetOrigin. This is safe because
handleWindowMessage independently validates event.origin on the
receiving side.

Co-authored-by: Stephanie Elliott <stephanieelliott@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants