You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
window.frames can reveal information about sites in a different origin, providing a side channel to break the same origin policy.
Description
Given two sites, site A and site B. Assume site B has a page where it renders an iframe for each instance of some content. For the purposes of this example, that iframe can be to another page on site B or to a third site. Site A can render a pop-up or an iframe to site B, retrieve a handle to the window, and get back the number of frames via otherWindow.frames.length. The number of pieces of content for a particular user on this page could be sensitive (comments, messages, search results, etc.), or even the existence of frames on the page could be a side channel (an iframe only rendered on a particular page for users with a specific role on that site), and so this api is therefore exposing a cross-origin side channel for that information.
Site A is also able to change the location of the iframes rendered in site B by calling otherWindow.frames[n].location.replace('...'). In this way, an attacker could change the content of a displayed iframe to display alternate information, or change the target of a * target origin postMessage (which is problematic to begin with, but closing this hole closes that hole).
Example:
This example uses iframes because it was quick to write, but it could just as easily use pop-ups (open a link with target _blank and get a window handle) to bypass XFO.
site-a/index.html:
<!doctype html><html><head><title>Site A</title></head><body><iframeid="target" src="http://localhost:8081/?n=6"></iframe><script>// give the other window a second to loadsetTimeout(()=>{varw=document.getElementById('target').contentWindowvarchild=document.createElement('b');child.innerHTML=w.frames.length;document.body.appendChild(child);},1000);</script></body></html>
running site-a as localhost:8080 and site-b as localhost:8081, eg: python3 -m http.server 808{0,1}
In this example, n is clearly not sensitive as it's a url parameter that site-a chose, but it could just as easily be based on a cookie value or other sensitive data that site-a should not be able to retrieve.
In the js console of site-a you can also do document.getElementById('target').contentWindow.frames[0].location.replace('http://some-other-site') to manipulate the iframe from another origin.
Note: this also works with window.length, window[0], etc.
Suggested Solution
Either prevent sites from accessing cross-origin frames at all, or limit them to accessing cross-origin frames that point back into their own origin, eg: a site-b with two iframes, one that points to site-b and one that points to site-a would return a window.frames.length of 1 when called from site-a.
The text was updated successfully, but these errors were encountered:
window.frames
can reveal information about sites in a different origin, providing a side channel to break the same origin policy.Description
Given two sites, site A and site B. Assume site B has a page where it renders an iframe for each instance of some content. For the purposes of this example, that iframe can be to another page on site B or to a third site. Site A can render a pop-up or an iframe to site B, retrieve a handle to the window, and get back the number of frames via
otherWindow.frames.length
. The number of pieces of content for a particular user on this page could be sensitive (comments, messages, search results, etc.), or even the existence of frames on the page could be a side channel (an iframe only rendered on a particular page for users with a specific role on that site), and so this api is therefore exposing a cross-origin side channel for that information.Site A is also able to change the location of the iframes rendered in site B by calling
otherWindow.frames[n].location.replace('...')
. In this way, an attacker could change the content of a displayed iframe to display alternate information, or change the target of a*
target origin postMessage (which is problematic to begin with, but closing this hole closes that hole).Example:
This example uses iframes because it was quick to write, but it could just as easily use pop-ups (open a link with target
_blank
and get a window handle) to bypass XFO.site-a/index.html:
site-b/index.html:
running site-a as
localhost:8080
and site-b aslocalhost:8081
, eg:python3 -m http.server 808{0,1}
In this example,
n
is clearly not sensitive as it's a url parameter that site-a chose, but it could just as easily be based on a cookie value or other sensitive data that site-a should not be able to retrieve.In the js console of site-a you can also do
document.getElementById('target').contentWindow.frames[0].location.replace('http://some-other-site')
to manipulate the iframe from another origin.Note: this also works with
window.length
,window[0]
, etc.Suggested Solution
Either prevent sites from accessing cross-origin frames at all, or limit them to accessing cross-origin frames that point back into their own origin, eg: a site-b with two iframes, one that points to site-b and one that points to site-a would return a window.frames.length of 1 when called from site-a.
The text was updated successfully, but these errors were encountered: