Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Injected iframe cleanup on error #1627

Open
1 task done
lapritchett opened this issue Jan 15, 2025 · 0 comments
Open
1 task done

[Bug]: Injected iframe cleanup on error #1627

lapritchett opened this issue Jan 15, 2025 · 0 comments
Labels
bug Something isn't working

Comments

@lapritchett
Copy link

Preflight Checklist

  • I have searched the issue tracker for a bug report that matches the one I want to file, without success.

What package is this bug report for?

Other (specify below)

Version

v2.0.0-alpha.18

Expected Behavior

@rrweb/record and rrweb-snapshot should clean up any iframes that are injected for the purposes of getting clean prototypes.

Actual Behavior

In @rrweb/record and rrweb-snapshot, getUntaintedPrototype contains code that injects an iframe but doesn't always properly clean it up (in my case, when calling const win = iframeEl.contentWindow; doesn't work within an iframe):

  try {
    const iframeEl = document.createElement("iframe");
    document.body.appendChild(iframeEl);
    const win = iframeEl.contentWindow;
    if (!win) return defaultObj.prototype;
    const untaintedObject = win[key].prototype;
    document.body.removeChild(iframeEl);
    if (!untaintedObject) return defaultPrototype;
    return untaintedBasePrototype[key] = untaintedObject;
  } catch {
    return defaultPrototype;
  }

Steps to Reproduce

Enable @rrweb/record
Go to https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe
Paste the following into the HTML input:

<iframe
  id="inlineFrameExample"
  title="Inline Frame Example"
  width="300"
  name="Example Website"
  src="https://example.com"
  title="Example.com"
  ref={iframeRef}
  sandbox="allow-scripts"
  height="200"
  src="">
</iframe>

Click on "Example Domain" when it renders in the iframe
Note a new blank iframe is injected and not removed
CleanShot 2025-01-14 at 18 16 42@2x

Testcase Gist URL

No response

Additional Information

I suggest adding a finally clause to handle the iframe cleanup:

  let iframeEl;
try {
  iframeEl = document.createElement("iframe");
  document.body.appendChild(iframeEl);
  const win = iframeEl.contentWindow;
  if (!win) return defaultObj.prototype;
  const untaintedObject = win[key].prototype;
  if (!untaintedObject) return defaultPrototype;
  return untaintedBasePrototype[key] = untaintedObject;
} catch {
  return defaultPrototype;
} finally {
  try {
    if (iframeEl && iframeEl.parentNode) {
      document.body.removeChild(iframeEl);
    }
  } catch (cleanupErr) {
    console.error('[getUntaintedPrototype2] cleanup error', cleanupErr);
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant