onbeforeunload allows attacker to hijack page load




Document Navigation
a year ago
8 months ago


(Reporter: Skansing, Unassigned)


(Blocks: 1 bug, {sec-low})

Firefox Tracking Flags

(Not tracked)




a year ago
User Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36

Steps to reproduce:

Visit in firefox and follow the instructions


- Make a page with the following script

<p>Change the url</p>

window.onbeforeunload = function()
  setTimeout(function() {
      window.document.writeln('<script>window.location.href = "//evil.com";<\/script>');

  }, 0);

  return "quux";

- Open the page
- Change the url to facbook.com in the address bar 

Actual results:

Firefox opens evil.com instead of the expected facebook.com

Expected results:

Victim should have opened facebook.com or been notificed that their intended navigation has been canceled.

The culprint is that adding a timeout to a unbeforeload event allows use of some methods that would not / should not be possible in the event.

In this case the attacker is able to write and execute scripts in window context before handling the loading of the new page.

This allows attackers to
- Snoop on users before they exit the page (forward sniffing)
- Phishing attacks
- Degrading from https to http on site which allow both.
- etc

Bonus: a setTimeout event inside a unbeforeload also allows the attacker to do alert dialogs after the user has confirmed to load the new page. 

I tested this on 
- Firefox 47 on Ubuntu 16.04
- Firefox 47.0.1 on Windows 8

Comment 1

a year ago
For the forward sniffing, I should mention that, whatever the victim enters in the url, the attacker can access it inside the setTimeout (inside the onbeforeunload). A quick repo can done by adding alert(document.domain) inside the setTimeout callback, it should flash quickly with the url enter.


a year ago
Summary: onbeforeunload allows attacker to hijack url entered. → onbeforeunload allows attacker to hijack page load

Comment 2

a year ago
Actually, ignore the forward sniffing, cant reproduce that anymore.


a year ago
Version: 47 Branch → unspecified
Olli, is this expected behavior? Is this a possible security issue we should fix?
Group: firefox-core-security → core-security
Component: Untriaged → Document Navigation
Flags: needinfo?(bugs)
Product: Firefox → Core
we do seem to prevent direct navigation in the onbeforeunload so this works around it (should check onunload too). Safari seems to have the same behavior we do (end up on example.com instead of the site you pick). Chrome initially loads example.com and then quickly replaces it with the site you entered into the location bar. Didn't play with the timeout value to see if a longer one would simply get canceled or if it would race with and replace the selected site.

Was not able to reproduce the more serious "forward sniffing" claim but I only spent a couple of minutes poking at this. Needs more investigation (or a PoC from the reporter)
Group: core-security → dom-core-security
Ever confirmed: true

Comment 5

a year ago
The forward sniffing was a false positive from me, I have to reproduce it without any success.

Comment 6

a year ago
*I have tried to reproduce it, without any success. So I am quite sure it was just me mistaken origins while testing.
Unhiding because the result doesn't seem terrible (user will end up hijacked, but should notice it's not the place they typed in).
Blocks: 432687
Group: dom-core-security
Keywords: sec-low
They might not notice if the page is disguised as another popular website and they're trying to navigate to that website.

Comment 9

a year ago
Feels like we should already have this on file somewhere, but maybe I'm wrong...

IIRC we set a flag when beforeunload fires and isn't cancelled, so maybe we should just deny navigation after that, full stop?

Comment 10

a year ago
I think the point was that this opens for phishing attack where the victim can not trust the url they just entered in the url.

I am not sure its great to have open?

Comment 11

a year ago
Dupe of bug 839470 and/or bug 1263100 ?
Let's go with bug 1263100 (we can always reverse).
Last Resolved: a year ago
Resolution: --- → DUPLICATE
Duplicate of bug: 1263100
Flags: needinfo?(bugs)
You need to log in before you can comment on or make changes to this bug.