The dangers from across browser-windows

While browsing the web, your browser does its best to protect you along the way, but sometimes fails to do so, if not instructed properly by the website you are surfing to.

One of the browsers most important security mechanisms is the Same-Origin Policy[1][2][3] (SOP), that restricts how scripts and documents from one origin can interact with resources and documents from another origin. This default protection may still not be enough to prevent an attacker from launching various attacks against users of your web application. In this post we will explore various attacks on browser windows and how to shut them down.

Attacks on browser windows

The basic idea behind an attack on a window is that an attacker controlling his own website (eve.com in the example) is somehow programmatically gaining access to a handle to a victim website (alice.com). This can be done in many ways and will not be prevented by the SOP. The attacker’s website may not be able to read or write cross-origin content but is still allowed to do a limited number of things.

To illustrate what could be done, the following code could be included on an attacker’s website:

// This is included in some javascript on eve.com
// Opening a window to alice.com where Bob is logged in
w = window.open(“alice.com”, “_blank”)

Now the attacker’s website (Eve’s website in the illustration) can do many malicious things:

// Send messages
w.postMessage(“hello”, “*”)
// Count frames
console.log(w.length)
// Navigate to another website
// Note that the lower-case L has been replaced by an upper-case i
w.location = “//aIice.com”
Simple Attack against Bob

The illustration describes the basic attack scenario which needs to happen so that any of the following attacks may succeed:

Often the target of these attacks is to exfiltrate information that is only available to the user of the victim site or phish the user of their login credentials. If attackers chain together multiple exploits, these attacks can become very powerful to extract information even if well protected.

Example 1: Chained XS Search

Bob is the administrator for a website (bob.com) and checks reports on issues with said website he manages. Additionally, there also exists an administrative interface (secure.admin) that Bob can access from inside his local network. Bobs administrative interface has a Query-Based Search System which allows him to query usernames and passwords. This system returns a page with frames for each result.

Eve happens to find a stored XSS vulnerability on Bobs website allowing her to inject any Javascript code on some page on Bobs website, which will get executed as soon as somebody opens that page. She carefully prepares a malicious Javascript snippet and injects it into the website. She then proceeds to send Bob a link to his own website complaining that something is wrong.

Bob opens the link, unbeknownst to him, the malicious Javascript code is opening hidden iframes of the secure administrative search interface with queries for username/password combinations. This can be done in many ways, but important here is that due to the results being represented in iframes, even though the secure administrative interface is secure on another origin (secure.admin), Bobs own website is turned against him and can read how many iframes are being generated on that locally secured site, basically allowing Eve’s script to enumerate credentials.

The basic Javascript code to achieve something like this could look like the following:

var iframe = document.createElement(“iframe”);
iframe.name = “xleaks”;
document.body.appendChild(iframe);
var win = window.open(“secure.admin/search?pwd=LIKE “ + knownPart + guessedCharacter + “.%”, “xsleaks”);
if(win.length != 0) {
      console.log(“Guessed char ” + guessedCharacter);
      // Send guessed character to alice and repeat
}
iframe.remove();

If credentials have been found, they will be further sent over to Eve by the malicious JavaScript snippet.

Complex XSS & XS Search Attack against Bob

It is worth noting that the SOP flaw can be exploited without the need for the XSS vulnerability. The XSS vulnerability is included in this example only to illustrate how vulnerabilities can be chained together to create a more severe attack.

Example 2: Tabnabbing

Bob navigates to his favorite social media site “toebook.com” and sees an ad for something he always wanted to have and decides to click it. The webpage looks normal and describes his item of choice. Bob takes his time and inspects the description carefully but, in the end, decides that he doesn’t trust the shady store that was advertised. He closes the store’s browser tab and returns to “toebook.com” only to find out that he has been logged out of the site! Eager to continue browsing he types in his login information and continues to the social media site. What he doesn’t know is that he just had his credentials phished by “t0ebook.com”.

The social media site usually opens ads with Javascript in such a way:

window.open(adsite, target=”_blank”)

During his stay on the Eve’s store page, malicious Javascript code tabnabbed him and navigated the original “toebook.com” tab to “t0ebook.com”, which has a copy of the login form of toebook that sends the credentials that are typed into its login form directly to Eve and redirects the user to the real “toebook.com”:

// Navigates the original toebook.com tab to a fake login form that looks just like the original toebook.com
window.opener.location.replace(“https://t0ebook.com”)
Reverse Tabnabbing Attack on Bob

Severing the Link

The main issue that allows these attacks to happen is that an attacker can obtain a reference to another browsing window. Although the malicious actor is limited by the SOP in what they can do with that window reference, not all possibilities are being blocked, thus, allowing for creative attacks.

Especially, as we have shown in the examples, attacks abusing the holes in the SOP can be combined with other exploits to pierce even through very defended setups and extract sensitive information.

To solve such issues, the browser can be instructed by a webserver to isolate a website’s window, not allowing other sites to obtain a reference at all. This can be achieved by adding the Cross-Origin-Opener-Policy (COOP)[8] to the response HTTP(S) header when the webserver is serving a web application.

The COOP works as following:

  • If it is set to “same-origin” and the origins of two pages match, they can interact with each other as we described.
  • If the opener’s COOP is set to “same-origin-allow-popups” and the openee’s COOP is set to the default “unsafe-none”, then the pages can interact with each other.
  • If one of the pages sets COOP, then the browser will create a new context group for each page with COOP, thus severing the link between pages.

If we execute our tabnabbing attack from before with COOP on “toebook.com” being set to “same-origin”, the redirection to the phishing site will be disallowed and throw a TypeError: window.opener is null.

Prevention of a Tabnabbing Attack

Conclusion

As we saw, it can be as easy as setting proper headers to protect against certain attacks against your web application from across browser windows, that the default SOP does not protect against. The crucial part here is to know that these headers exist and can instruct browsers to isolate your web application and thus give users the protection they deserve.

Additionally, to further protect your web application more headers that can be used in conjunction with COOP exist, such as the Cross-Origin-Embedder-Policy (COEP)[9] and Cross-Origin-Resource-Policy (CORP)[10] which are worth looking into to further isolate your web application and defend against attacks such as Spectre[11], for which proof-of-concept attacks have been demonstrated[12][13].


[1] https://web.dev/same-origin-policy/
[2] https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
[3] https://appsecmonkey.com/blog/same-origin-policy
[4] https://xsleaks.dev/docs/attacks/xs-search/
[5] https://xsleaks.dev/
[6] https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html#tabnabbing
[7] https://security.googleblog.com/2021/03/a-spectre-proof-of-concept-for-spectre.html
[8] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy
[9] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy
[10] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy
[11] https://web.dev/why-coop-coep/
[12] https://security.googleblog.com/2021/03/a-spectre-proof-of-concept-for-spectre.html
[13] https://leaky.page/