Skip to content
This repository was archived by the owner on May 7, 2026. It is now read-only.

fix(record): handle SecurityError on ownerDocument access in Firefox#173

Draft
posthog[bot] wants to merge 1 commit into
mainfrom
posthog-code/handle-securityerror-on-ownerdocument-access
Draft

fix(record): handle SecurityError on ownerDocument access in Firefox#173
posthog[bot] wants to merge 1 commit into
mainfrom
posthog-code/handle-securityerror-on-ownerdocument-access

Conversation

@posthog
Copy link
Copy Markdown
Contributor

@posthog posthog Bot commented Apr 27, 2026

Summary

A new error-tracking issue surfaced on 2026-04-27 for Error: Permission denied to access property "ownerDocument" originating in @posthog/rrweb-record 0.0.60. The minified stack shows a tight loop of internal helper calls inside rrweb-record.js with no application frames, in the same family as the cross-origin SecurityErrors fixed by 50bf563, e06b822, and a0e18f1.

In Firefox, when a same-origin iframe later navigates cross-origin, reading ownerDocument on a node whose owning document is now cross-origin throws "Permission denied to access property 'ownerDocument'" (a SecurityError-named DOMException). Several ownerDocument reads in the record bundle were not wrapped, so the throw escaped from low-level helpers and aborted the surrounding mutation / shadow-DOM observer callback — exactly the failure mode 50bf563 fixed for attachIframe.

Changes

  • packages/rrweb/src/utils.ts — read ownerDocument through a small safeOwnerDocument helper that returns null if the access throws, so inDom and shadowHostInDom treat the node as not in the DOM (the safe default for both callers in mutation.ts pushAdd and the patched attachShadow in shadow-dom-manager.ts) instead of re-throwing.
  • packages/rrweb/src/record/observer.ts — wrap the host.ownerDocument?.defaultView?.ShadowRoot lookup in initAdoptedStyleSheetObserver with a try/catch that swallows DOMException SecurityError and bails out with a no-op cleanup handler. Other exception types still propagate.
  • Regression tests in packages/rrweb/test/util.test.ts and packages/rrweb/test/record/observer.test.ts install an ownerDocument getter that throws a SecurityError-named DOMException and assert the call sites do not re-throw — mirroring the regression test introduced in 50bf563.

Test plan

  • pnpm --filter @posthog/rrweb retest test/util.test.ts test/record/observer.test.ts — all unit tests pass
  • pnpm --filter @posthog/rrweb check-types — clean
  • Verify in Firefox on a page with a same-origin iframe that subsequently navigates cross-origin

Created with PostHog Code

In Firefox, reading `ownerDocument` on a node whose owning document has
navigated cross-origin throws "Permission denied to access property
'ownerDocument'" (a SecurityError variant). The unguarded reads in
`inDom`, `shadowHostInDom`, and `initAdoptedStyleSheetObserver` could
abort the surrounding mutation/shadow-DOM observer callback, in the same
family of failures fixed by 50bf563, e06b822, and a0e18f1 for
`attachIframe`.

- `inDom`/`shadowHostInDom`: read `ownerDocument` through a small helper
  that returns `null` if the access throws, so callers treat the node as
  not in the DOM rather than re-throwing.
- `initAdoptedStyleSheetObserver`: wrap the
  `host.ownerDocument?.defaultView?.ShadowRoot` lookup and bail out with
  a no-op cleanup handler when a `SecurityError` is thrown.
- Add regression tests covering both code paths with a node whose
  `ownerDocument` getter throws a `SecurityError`-named DOMException.

Generated-By: PostHog Code
Task-Id: 157b8b4a-321b-43ff-bb3b-dd519222e01e
@github-actions
Copy link
Copy Markdown
Contributor

Size Change: +3.05 kB (+0.03%)

Total Size: 10.9 MB

Filename Size Change
packages/all/dist/rrweb-all.cjs 611 kB +291 B (+0.05%)
packages/all/dist/rrweb-all.js 610 kB +291 B (+0.05%)
packages/all/dist/rrweb-all.umd.cjs 614 kB +296 B (+0.05%)
packages/all/dist/rrweb-all.umd.min.cjs 290 kB +142 B (+0.05%)
packages/record/dist/rrweb-record.cjs 172 kB +289 B (+0.17%)
packages/record/dist/rrweb-record.js 172 kB +289 B (+0.17%)
packages/record/dist/rrweb-record.umd.cjs 174 kB +293 B (+0.17%)
packages/record/dist/rrweb-record.umd.min.cjs 83.7 kB +142 B (+0.17%)
packages/rrweb/dist/rrweb.cjs 594 kB +291 B (+0.05%)
packages/rrweb/dist/rrweb.js 593 kB +291 B (+0.05%)
packages/rrweb/dist/rrweb.umd.cjs 595 kB +296 B (+0.05%)
packages/rrweb/dist/rrweb.umd.min.cjs 281 kB +142 B (+0.05%)
ℹ️ View Unchanged
Filename Size
packages/packer/dist/base.js 18.2 kB
packages/packer/dist/base.cjs 18.3 kB
packages/packer/dist/base.umd.cjs 19.4 kB
packages/packer/dist/base.umd.min.cjs 10.1 kB
packages/packer/dist/pack.cjs 347 B
packages/packer/dist/pack.js 285 B
packages/packer/dist/pack.umd.cjs 2.28 kB
packages/packer/dist/pack.umd.min.cjs 1.76 kB
packages/packer/dist/packer.cjs 257 B
packages/packer/dist/packer.js 136 B
packages/packer/dist/packer.umd.cjs 1.31 kB
packages/packer/dist/packer.umd.min.cjs 1.27 kB
packages/packer/dist/unpack.cjs 769 B
packages/packer/dist/unpack.js 702 B
packages/packer/dist/unpack.umd.cjs 1.82 kB
packages/packer/dist/unpack.umd.min.cjs 1.6 kB
packages/plugins/rrweb-plugin-canvas-webrtc-record/dist/rrweb-plugin-canvas-webrtc-record.cjs 37.6 kB
packages/plugins/rrweb-plugin-canvas-webrtc-record/dist/rrweb-plugin-canvas-webrtc-record.js 37.5 kB
packages/plugins/rrweb-plugin-canvas-webrtc-record/dist/rrweb-plugin-canvas-webrtc-record.umd.cjs 38.7 kB
packages/plugins/rrweb-plugin-canvas-webrtc-record/dist/rrweb-plugin-canvas-webrtc-record.umd.min.cjs 22.9 kB
packages/plugins/rrweb-plugin-canvas-webrtc-replay/dist/rrweb-plugin-canvas-webrtc-replay.cjs 34.3 kB
packages/plugins/rrweb-plugin-canvas-webrtc-replay/dist/rrweb-plugin-canvas-webrtc-replay.js 34.2 kB
packages/plugins/rrweb-plugin-canvas-webrtc-replay/dist/rrweb-plugin-canvas-webrtc-replay.umd.cjs 35.4 kB
packages/plugins/rrweb-plugin-canvas-webrtc-replay/dist/rrweb-plugin-canvas-webrtc-replay.umd.min.cjs 21.2 kB
packages/plugins/rrweb-plugin-console-record/dist/rrweb-plugin-console-record.cjs 14.9 kB
packages/plugins/rrweb-plugin-console-record/dist/rrweb-plugin-console-record.js 14.8 kB
packages/plugins/rrweb-plugin-console-record/dist/rrweb-plugin-console-record.umd.cjs 16 kB
packages/plugins/rrweb-plugin-console-record/dist/rrweb-plugin-console-record.umd.min.cjs 8 kB
packages/plugins/rrweb-plugin-console-replay/dist/rrweb-plugin-console-replay.cjs 5.01 kB
packages/plugins/rrweb-plugin-console-replay/dist/rrweb-plugin-console-replay.js 4.9 kB
packages/plugins/rrweb-plugin-console-replay/dist/rrweb-plugin-console-replay.umd.cjs 6.1 kB
packages/plugins/rrweb-plugin-console-replay/dist/rrweb-plugin-console-replay.umd.min.cjs 3.3 kB
packages/plugins/rrweb-plugin-sequential-id-record/dist/rrweb-plugin-sequential-id-record.cjs 681 B
packages/plugins/rrweb-plugin-sequential-id-record/dist/rrweb-plugin-sequential-id-record.js 548 B
packages/plugins/rrweb-plugin-sequential-id-record/dist/rrweb-plugin-sequential-id-record.umd.cjs 1.79 kB
packages/plugins/rrweb-plugin-sequential-id-record/dist/rrweb-plugin-sequential-id-record.umd.min.cjs 1.5 kB
packages/plugins/rrweb-plugin-sequential-id-replay/dist/rrweb-plugin-sequential-id-replay.cjs 933 B
packages/plugins/rrweb-plugin-sequential-id-replay/dist/rrweb-plugin-sequential-id-replay.js 820 B
packages/plugins/rrweb-plugin-sequential-id-replay/dist/rrweb-plugin-sequential-id-replay.umd.cjs 2.04 kB
packages/plugins/rrweb-plugin-sequential-id-replay/dist/rrweb-plugin-sequential-id-replay.umd.min.cjs 1.64 kB
packages/replay/dist/rrweb-replay.cjs 440 kB
packages/replay/dist/rrweb-replay.js 440 kB
packages/replay/dist/rrweb-replay.umd.cjs 443 kB
packages/replay/dist/rrweb-replay.umd.min.cjs 210 kB
packages/replay/dist/style.css 2.45 kB
packages/replay/dist/style.min.css 1.97 kB
packages/rrdom-nodejs/dist/rrdom-nodejs.cjs 150 kB
packages/rrdom-nodejs/dist/rrdom-nodejs.js 149 kB
packages/rrdom-nodejs/dist/rrdom-nodejs.umd.cjs 152 kB
packages/rrdom-nodejs/dist/rrdom-nodejs.umd.min.cjs 71.4 kB
packages/rrdom/dist/rrdom.cjs 174 kB
packages/rrdom/dist/rrdom.js 173 kB
packages/rrdom/dist/rrdom.umd.cjs 176 kB
packages/rrdom/dist/rrdom.umd.min.cjs 81.4 kB
packages/rrweb-player/dist/events.js 159 kB
packages/rrweb-player/dist/global.css 240 B
packages/rrweb-player/dist/rrweb-player.cjs 511 kB
packages/rrweb-player/dist/rrweb-player.js 511 kB
packages/rrweb-player/dist/rrweb-player.umd.cjs 514 kB
packages/rrweb-player/dist/rrweb-player.umd.min.cjs 239 kB
packages/rrweb-player/dist/style.css 5.57 kB
packages/rrweb-player/dist/style.min.css 5 kB
packages/rrweb-snapshot/dist/record.cjs 31.3 kB
packages/rrweb-snapshot/dist/record.js 30.3 kB
packages/rrweb-snapshot/dist/record.umd.cjs 53 kB
packages/rrweb-snapshot/dist/record.umd.min.cjs 25.8 kB
packages/rrweb-snapshot/dist/replay.cjs 137 kB
packages/rrweb-snapshot/dist/replay.js 137 kB
packages/rrweb-snapshot/dist/replay.umd.cjs 160 kB
packages/rrweb-snapshot/dist/replay.umd.min.cjs 74.2 kB
packages/rrweb-snapshot/dist/rrweb.cjs 2.13 kB
packages/rrweb-snapshot/dist/rrweb.js 1.32 kB
packages/rrweb-snapshot/dist/rrweb.umd.cjs 216 kB
packages/rrweb-snapshot/dist/rrweb.umd.min.cjs 91.6 kB
packages/rrweb-snapshot/dist/types.cjs 18.1 kB
packages/rrweb-snapshot/dist/types.umd.cjs 19.3 kB
packages/rrweb-snapshot/dist/types.umd.min.cjs 9.85 kB
packages/rrweb-snapshot/dist/types.js 17.7 kB
packages/rrweb/dist/style.css 2.45 kB
packages/rrweb/dist/style.min.css 1.97 kB
packages/types/dist/rrweb-types.cjs 5.64 kB
packages/types/dist/rrweb-types.js 5.38 kB
packages/types/dist/rrweb-types.umd.cjs 6.69 kB
packages/types/dist/rrweb-types.umd.min.cjs 3.44 kB
packages/utils/dist/rrweb-utils.cjs 6.41 kB
packages/utils/dist/rrweb-utils.js 5.95 kB
packages/utils/dist/rrweb-utils.umd.cjs 7.47 kB
packages/utils/dist/rrweb-utils.umd.min.cjs 4.16 kB

compressed-size-action

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants