Open
Description
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
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);
}
}