Open Bug 1392249 Opened 3 years ago Updated 2 years ago

popup window navigates to another domain but JavaScript from the original domain continues executing

Categories

(Core :: DOM: Core & HTML, defect, P3)

55 Branch
defect

Tracking

()

UNCONFIRMED

People

(Reporter: jpg.inc.au, Unassigned)

Details

Attachments

(1 file)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36

Steps to reproduce:

Not sure if i filled in the version properly. tested on windows version 55.0.2 

from window 'foo' open a popup, 'bar'. 

in a script tag in the <head> of bar if you navigate to another domain followed immediately by an alert on foo, bar will navigate to the new domain with the alert showing on foo. 

when the alert on foo is dismissed the javascript after the alert on bar is executed even though the window is now in another domain.

When testing i couldn't find any instances that allowed UXSS however I observed some strange behaviors. For example. If the javascript on bar after the alert is:

while(true){1+1}

after a few seconds the script will time out with a message in bar's console saying a long running script has been stopped. If you instead do

opener.eval('while(true){1+1}') 

the script won't time out anymore, even if you close the opener. the javascript form the original domain will continue running even though no tabs with that domain exist anymore. After a while firefox will show a message ribbon on the top of the browser asking if you want to stop a script because it is slowing down the browser.

It is also possible to access document.cookie in the phantom javascript.

It is also possible to send an xml http request from this phantom javascript by creating a refernce to the opener's document, and sending the xlmhttprequest from the openers document. if you attempt to perform the send() function in the context of the phantom process it fails, the error message is something like it is in an invalid context.

This could be abused to perform things like hash cracking along with a way to exfil the results (xmlhttprequest). 

if you open("the POC attached to this bug report.html") it will perform a while loop for 25 seconds followed by an xmlhttp request even if you close the opening window. the xmlhttp request will fire even if you click the ribbon to stop the javascript. I started experimenting with ways to get around the 'stop javascript executing' ribbon and have had some small success.

I'm a relatively new security researcher and I hope that you might consider this eligible for a security bug bounty. I will continue to research this issue and report anything that would be of a high security impact


Actual results:

Window navigated to another domain and the original domain's javascript continued to run in the background


Expected results:

The window should have either stopped executing the javascript once the navigation to another domain occurred OR not have navigated to the other domain until the Javascript finished.
Group: firefox-core-security → dom-core-security
Component: Untriaged → DOM
Product: Firefox → Core
I'm not exactly sure what we want to do in this case. Script in bfcache continues to execute is expected [1]:

> In the bfcache case, freezing the window just marks it as frozen; the DOM is preserved, as are compiled script objects. 
> Thawing marks it as thawed. Freezing suspends timeouts and interval timers on the frozen window, so they won't execute. 
> The script that's running when the window is frozen runs to completion, as it would if it were being closed

We have to guarantee run-to-competition, right?

[1] https://developer.mozilla.org/en-US/docs/Working_with_BFCache
When the popup window in the POC provided runs on an already opened window (e.g. a named window), the JavaScript runs to completion and then the page loads the new domain (as opposed to loading the new domain and continuing to run the old domain's JavaScript in the background). I think that is the expected behavior?
Not familiar with the spec enough... :/

Boris, do you have some comments on what the expected behavior should be in the test case of comment 0?
Flags: needinfo?(bzbarsky)
I was thinking about this last night. Perhaps this behavior is occurring because the line in the POC:

window.location.href = "https://www.google.com/" 

Doesn't add an entry in the history and the BF Cache gets confused?
Per spec, while the alert is up the event loop should be completely frozen and hence the navigation should not complete.  This is, obviously, completely user-hostile.

That said, I don't think there's a security problem here.  In general, script in a navigated-away-from window can run.  As a simple example, say the popup just created a function inside itself and handed that function object to the opener.  Then it did the navigation.  The opener could then wait for the navigation to complete (it can poll for this by using a setInterval to poke properties on the popup until it gets a security exception, say, or the function could get handed back in the unload event in the popup to start with) and then call the function.  In that situation most browsers (but not Edge) will run the script.

In fact, we have run into sites that expect functions from closed tabs to run in a situation like the above where some other tab is holding on to the function.

In terms of its security properties, I don't think using the event-loop-spinning that alert() does to complete the navigation and then unwind into the already-running script is any different than doing the navigation and then getting your code called by the opener.
Flags: needinfo?(bzbarsky)
A couple of notes regarding security.

1. the script continues to run even after the opener is closed. I started experimenting with ways to restart the script after "stop script" message ribbon on the top of the browser is clicked and had some success.
2. postMessage's source is set to the window that has already navigated to the new domain. This is only an issue if a developer trusts the message if it originates from its own window and doesn't check the event's origin.

Obviously these are rather minor...

I'm happy to continue researching and will report back if I find anything more serious. Let me know your thoughts
(In reply to Boris Zbarsky [:bz] (still digging out from vacation mail) from comment #5)
> Per spec, while the alert is up the event loop should be completely frozen
> and hence the navigation should not complete.  This is, obviously,
> completely user-hostile.

Maybe you can look into just this part, Samael?
Flags: needinfo?(sawang)
Priority: -- → P3
To be clear, we are very purposefully _not_ implementing the user-hostile part of the spec here.  Once quantum DOM is done, we might be able to shut down some of the tabgroup event loop bits and thus prevent the navigation from completing, if we care.
It looks we don't want to change the implementation at this moment.
Flags: needinfo?(sawang)
Group: dom-core-security
Component: DOM → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.