Skip to content

SITES-51937: Add allow="local-network-access" to extension iframes - #155

Merged
kokoc merged 2 commits into
mainfrom
SITES-51937-local-network-access
Sep 21, 2026
Merged

kokoc merged 2 commits into
mainfrom
SITES-51937-local-network-access

Conversation

@fe-lix-

@fe-lix- fe-lix- commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Description

Sets allow="local-network-access" on every iframe uix-host creates for extensions (both the hidden guest-server frame and the visible guest-UI frame), by adding it to requiredIframeProps in packages/uix-host/src/dom-utils/iframe-normalizers.ts -- the single place both iframe types get their attributes from (port.ts's connect()/attachFrame() via normalizeIframe(), and GuestUIFrame.tsx via spreading requiredIframeProps).

Motivation and Context

Related to SITES-48168. When a user's network resolves the author-* host to a private/CGNAT IP (e.g. Zscaler for BYOD users), Chrome's Local Network Access feature silently blocks requests from UE's extension iframes to that host -- confirmed via HAR showing repeated net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS errors, with no permission prompt shown.

Since requiredIframeProps is spread/applied last (after any consumer-provided props), this required allow value intentionally wins over any custom allow a host app might pass -- same precedent as the other required props (data-uix-guest, role, referrerPolicy). No existing usage of a custom allow prop exists anywhere in this repo's examples/e2e apps today, so this isn't expected to break anyone.

Related Issue

SITES-51937

How Has This Been Tested?

  • npx jest packages/uix-host/src/dom-utils/iframe-normalizers.test.ts -- updated inline snapshot confirms normalizeIframe() now sets allow="local-network-access" (this covers the guest-server frame path).
  • Added a test to GuestUIFrame.test.tsx confirming the rendered guest-UI iframe gets allow="local-network-access", including when a consumer passes a conflicting custom allow prop.
  • npm run lint && npm run test:unit -- 15/15 suites, 87 tests (85 passed + 2 pre-existing skipped), 0 failing.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • I have added tests to cover my changes.
  • All new and existing tests passed.

Follow-up (per ticket's acceptance criteria)

Once this merges and ships in a release, update SITES-48168 with the uix-* version that carries the fix, so it can be verified there.

🤖 Generated with Claude Code

fe-lix- and others added 2 commits September 21, 2026 15:29
Chrome's Local Network Access checks silently block requests from
extension iframes when the author-* host resolves to a private/CGNAT
IP (e.g. some corporate proxies/BYOD setups) -- no permission prompt
is shown, just a net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS in
the console.

requiredIframeProps in iframe-normalizers.ts is the single place both
the guest server frame (port.ts's connect()) and the guest UI frame
(GuestUIFrame.tsx) get their iframe attributes from, so adding it
there covers every iframe uix-host creates for extensions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Unit tests only proved the attribute string was set on a jsdom node.
Add TestCafe assertions against the actual rendered iframes in
e2e/host-app: the visible GuestUIFrame (#iframe-for-guest) and the
hidden guest-server frame (identified by aria-hidden="true", which
only that frame sets), so a build step that strips the attribute
would be caught here too.

Verified both new assertions actually catch a regression: reverted
the allow: "local-network-access" line in iframe-normalizers.ts,
rebuilt, and re-ran against the live apps -- both failed with
"expected local-network-access, got null". Restored the fix and
re-ran clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@kokoc
kokoc merged commit 24e412a into main Sep 21, 2026
5 checks passed
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.

3 participants