Skip to content

fix(iframe-manager): prevent memory leak for sandboxed iframes without allow-scripts#135

Closed
Dhruv317 wants to merge 1 commit intoPostHog:mainfrom
Dhruv317:fix/sandboxed-iframe-memory-leak
Closed

fix(iframe-manager): prevent memory leak for sandboxed iframes without allow-scripts#135
Dhruv317 wants to merge 1 commit intoPostHog:mainfrom
Dhruv317:fix/sandboxed-iframe-memory-leak

Conversation

@Dhruv317
Copy link

Problem

For sandboxed iframes that don't have allow-scripts, rrweb cannot inject scripts into the iframe, so attachIframe() / onIframeLoad never fires. This means the attachedIframes Map is never populated for these iframes.

When the iframe is removed from the DOM, removeIframeById() tries to find the iframe element via:

  1. attachedIframes.get(id) - fails (never populated)
  2. mirror.getNode(id) - fails (mirror was already cleaned up by the mutation observer before removeIframeById is called)

As a result, crossOriginIframeMap and iframes WeakMaps are never cleaned, causing the iframe element and its contentWindow to be retained in memory indefinitely.

Solution

Populate attachedIframes immediately in addIframe() with a null content placeholder. If attachIframe() is called later (for non-sandboxed iframes), it updates the content. This ensures removeIframeById() can always find the element reference for cleanup.

Test plan

  • Added test case for sandboxed iframes without allow-scripts
  • Added test case verifying attachIframe() updates content correctly after addIframe()
  • All existing tests pass

Related

Fixes PostHog/posthog-js#2418

Made with Cursor

…t allow-scripts

For sandboxed iframes that don't have `allow-scripts`, rrweb cannot inject
scripts into the iframe, so `attachIframe()` / `onIframeLoad` never fires.
This means `attachedIframes` Map is never populated for these iframes.

When the iframe is removed from the DOM, `removeIframeById()` tries to find
the iframe element via:
1. `attachedIframes.get(id)` - fails (never populated)
2. `mirror.getNode(id)` - fails (mirror was already cleaned up)

As a result, `crossOriginIframeMap` and `iframes` WeakMaps are never cleaned,
causing the iframe element and its contentWindow to be retained in memory.

This fix populates `attachedIframes` immediately in `addIframe()` with a null
content placeholder. If `attachIframe()` is called later (for non-sandboxed
iframes), it updates the content. This ensures `removeIframeById()` can always
find the element reference for cleanup.

Fixes memory leak reported at: PostHog/posthog-js#2418

Co-authored-by: Cursor <cursoragent@cursor.com>
@Dhruv317
Copy link
Author

Closing for now - need to verify the fix locally first. Will reopen once tested.

@Dhruv317 Dhruv317 closed this Feb 27, 2026
@Dhruv317 Dhruv317 deleted the fix/sandboxed-iframe-memory-leak branch February 27, 2026 02:26
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.

Memory leak when using posthog-js with an iframe

1 participant