Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WindowProxy exposes cross-origin side channel #4005

Open
jakemco opened this issue Sep 5, 2018 · 3 comments
Open

WindowProxy exposes cross-origin side channel #4005

jakemco opened this issue Sep 5, 2018 · 3 comments
Labels
security/privacy There are security or privacy implications topic: multiple globals

Comments

@jakemco
Copy link

jakemco commented Sep 5, 2018

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>
    <iframe id="target" src="http://localhost:8081/?n=6"></iframe>
    <script>

// give the other window a second to load
setTimeout(() => {
  var w = document.getElementById('target').contentWindow
  var child = document.createElement('b');
  child.innerHTML = w.frames.length;
  document.body.appendChild(child);
}, 1000);
    </script>
  </body>
</html>

site-b/index.html:

<!doctype html>
<html>
  <head>
    <title>Site B</title>
  </head>
  <body>
    <script>
var urlParams = new URLSearchParams(window.location.search);
var n = urlParams.has('n') ? parseInt(urlParams.get('n'), 10) : 1;
for(var i = 0; i < n; ++i) {
  var child = document.createElement('iframe');
  child.src = 'https://www.facebook.com/plugins/like.php?href=https://github.com/whatwg/html';
  child.height = '20';
  document.body.appendChild(child);
}
    </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.

@rniwa
Copy link

rniwa commented Sep 5, 2018

See #3740 for a proposal to limit this to some extent.

@annevk annevk added security/privacy There are security or privacy implications topic: multiple globals labels Sep 6, 2018
@annevk annevk changed the title window.frames exposes cross-origin side channel WindowProxy exposes cross-origin side channel Sep 6, 2018
@annevk
Copy link
Member

annevk commented Sep 6, 2018

See also #1509 for a similar issue.

@domenic
Copy link
Member

domenic commented Sep 6, 2018

For anyone else momentarily confused, remember that window.frames === window, so this is not something frames-related, it's just how windows work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
security/privacy There are security or privacy implications topic: multiple globals
Development

No branches or pull requests

4 participants