Closed Bug 700080 (CVE-2012-4200) Opened 13 years ago Closed 12 years ago

URL and SSL/TLS Spoofing with onBlur using window.open(), alert() and window.close()

Categories

(Firefox :: Tabbed Browser, defect)

7 Branch
defect
Not set
normal

Tracking

()

VERIFIED FIXED
Firefox 17
Tracking Status
firefox10 --- wontfix
firefox11 - wontfix
firefox12 + wontfix
firefox13 + wontfix
firefox14 --- wontfix
firefox15 --- wontfix
firefox16 --- affected
firefox17 --- verified
firefox-esr10 --- wontfix

People

(Reporter: jordi.chancel, Unassigned)

References

()

Details

(Keywords: sec-high, verifyme, Whiteboard: [adv-track-main17-][sg:high] embargo until EOL ESR10; fixed by bug 391834)

Attachments

(5 files, 7 obsolete files)

Attached image ScreenShot1 (obsolete) —
User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1
Build ID: 20110928134238

Steps to reproduce:

The problem originated is from the creation of a link with javascript (window.open() ; alert() ; window.close()...) . 
When you open a new tab via window.open on another page (same domain) and this page use all of this JavaScript elements,  it's possible to spoof the URL (URL of targeted website) and SSL/TLS (SSL/TLS indicia of the spoofed URL), (see the screenshot please).

_/!\_ The testcase isn't perfect and require some interactions of the user for the moment. Please view this video for know how the spoofing works now => http://www.youtube.com/watch?v=0kjbrwo7egQ     _/!\_


Actual results:

URL with SSL/TLS is Spoofed like a High severity spoofing vulnerability.

(So i think the severity of this vulnerability is [sg:high] but for instant the testcase require some interactions of user [wich can probably be automated by JavaScript] and it severity is probably [sg:Moderate] if you don't want [sg:High] for now.)
This vulnerability was found and exploited by some tests of Jordi Chancel (me) and Eddy Bordi (Researcher at Alternativ-Testing.fr and Consultant of Vulnerability.fr).
For using this testcase => http://www.alternativ-testing.fr/Research/Mozilla/Mozilla%20Firefox%20High%20URL%20SSL%20TLS%20Bar%20Spoof6sd874c9dsc94x8d8972x/url1.html , you should accept popups from this website, thanks.
Attached file TESTCASE0.1 (obsolete) —
Testcase 0.1
Attachment #572304 - Attachment is obsolete: true
Attached file TESTCASE 0.2 (obsolete) —
TestCase 0.2
Confirming this bug.  The testcase in comment 2 leads to very bizarre behavior, but I'm not sure yet if it's useful as an exploit.

Clicking that URL and dismissing the alert seems to open and close a google tab that winds up painted in the space where the opener tab used to be, but without any usable UI.  You cannot click links, interact with the form, get a context menu, open the Web Console, or do just about anything with the page.  If you switch focus to another tab, you "lose" the spoofed tab.  The location bar is spoofed, sure. But what would the value be to an attacker if you can't interact with the page at all?  I'm having a hard time rating this one.

CC'ing Gavin since there are also some uncaught exceptions in browser.xml relating to switching and closing tabs that could potentially lead to other problems.
Status: UNCONFIRMED → NEW
Ever confirmed: true
@Brandon Sterne : with the new testcase 0.2 => http://www.alternativ-testing.fr/Research/Mozilla/Mozilla%20Firefox%20High%20URL%20SSL%20TLS%20Bar%20Spoof6sd874c9dsc94x8d8972x/2/url1.html , I can click links, interact with the form, get a context menu, open the web console etc...

Please use this new testcase please , i go post a video for demonstrate this.
Please use the testcase 0.2 to show the severity of this new vulnerability.
I think in the worst case this vulnerability is moderate if not high.

So please visit this new link => http://www.alternativ-testing.fr/Research/Mozilla/Mozilla%20Firefox%20High%20URL%20SSL%20TLS%20Bar%20Spoof6sd874c9dsc94x8d8972x/2/url1.html to update the severity of this vulnerability, with this proof of concept, page spoofed can use JavaScript and interact with the forms, click links, etc. (which was not possible with the testcase 0.1) .. .
I'll post a video on youtube and post it here in the next comment to show you this.
So view this video => http://www.youtube.com/watch?v=Ma_InlJsxls

sg:Moderate or sg:High ?
I can confirm the behavior in comment 7. Once the Google tab is closed, the tab goes away but the navigation bar stops updating. So if you do happen to navigate this zombie tab (through content only, e.g. following links) the location bar will continue to say Google.

This is clearly a bug, but I am still unconvinced as to its value as part of an attack. Sure, you can open a page to banking-site.com, but in order for the victim to enter anything sensitive into a phishing site, they would have to navigate this zombie tab over to the phishing site themselves, and only by following links from the banking-site.  I don't see how that could reasonably happen.

Of course you could also make a user go to attacker-site.com and have them navigate away while still thinking they're on attacker-site.com, but I don't see how that has any value either.

Am I missing some part of the attack?
Yes, but it's possible for attacker.com to show the google.com content automaticaly.
So I think this can be inversed and google.com can automaticaly show attacker.com content (not demonstrated yet) .

I will try to code a proof of concept wich demonstrates this.
moz_bug_r_a4: we're clearly in an odd state here. Can you find a way to abuse it?
The odd state is probably more in content-land than up in the tabbrowser front-end code.
Component: General → DOM: Core & HTML
Product: Firefox → Core
QA Contact: general → general
This actually looks like mostly a tabbrowser issue, caused in part by a strange interaction with tab-modal prompts. I saw a couple of "this.selectedTab is null" exceptions, which certainly shouldn't be happening. I haven't had a chance to look into it further.
Component: DOM: Core & HTML → General
Product: Core → Firefox
QA Contact: general → general
(In reply to Brandon Sterne (:bsterne) from comment #9)
> I can confirm the behavior in comment 7. Once the Google tab is closed, the
> tab goes away but the navigation bar stops updating. So if you do happen to
> navigate this zombie tab (through content only, e.g. following links) the
> location bar will continue to say Google.
> 
> This is clearly a bug, but I am still unconvinced as to its value as part of
> an attack. Sure, you can open a page to banking-site.com, but in order for
> the victim to enter anything sensitive into a phishing site, they would have
> to navigate this zombie tab over to the phishing site themselves, and only
> by following links from the banking-site.  I don't see how that could
> reasonably happen.
> 

An attacker's script can navigate a zombie tab to a phishing site.

I'll attach a phishing testcase.
Attached file phishing testcase
Attached image screenshot (obsolete) —
Thanks @moz_bug_r_a4@yahoo.com !
So this testcase works with user interaction for close the tab but this new Proof of Concept is better than the testcase 0.2 . what is the severity of this issue ? [sg:low]? [sg:moderate]? [sg:high]?
I think that this new vulnerability can be high or in the worst case moderate isn't it?
If we redirect the user to a blank page without any interaction possible (example https://accounts.google.com/ServiceLogin%), he will close the tab in most of case.
I've found a way for spoofed the URL and SSL/TLS WITHOUT CLOSE A TAB MANUALLY ! ! !
This Testcase works only for Mozilla Firefox 3.6.X for the moment, but a similar exploitation with Firefox 8.0 is probably possible.

I will posted the new video, and the new testcase (similar at the proof of concept of Moz_bug_r_a4 , but now, the user will just clicked two links for enable the spoofing, without close a tab manually).

With this new testcase, JavaScript and forms are disabled but we can click on links that allow to write LOGIN and PASSWORD with a visual numeric keyboard (View the next video).
Video of the new Testcase without close a tab manually => http://www.youtube.com/watch?v=3XobLRzLsOk
I had a similar testcase that worked with Firefox 8.0 that automatically closed
a tab and loaded a fake page.  But, I could not find a way to do phishing in a
fake page without JS and forms.

Now, I noticed that a subframe's JS and forms can work even when a tab is
automatically closed.

I'll attach two testcases that work with trunk, 8.0 and 3.6.
Attached file phishing testcase 2
This works with two links.
Attached file phishing testcase 3
This works without user interaction.  But, this works only if a user disabled
the pop-up blocker or allowed pop-ups for this site.
Eddy Bordi have firstly discovered a way for show a webpage without Tab.

Jordi Chancel have secondly reported a way that require multiple interactions of the user wich lead to an URL SSL/TLS Spoofing (testcase 0.1 and screenshot1).

Jordi Chancel have thirdly reported a way for use JavaScript , forms and links on the spoofing's page(testcase 0.2).

Jordi Chancel explains than we can probably use this bug for show the spoofing page automaticaly , so that banking website URL show Attacker website content without clicked link (comment 10).

Moz_bug_r_a4 demonstrate that it's possible to spoof URL SSL/TLS without click a link on the banking website (phishing testcase).

Jordi Chancel reported a testcase on firefox 3.6.24 wich lead to the URL SSL/TLS spoofing WITHOUT CLOSE THE TAB MANUALLY, but we can only click links, JavaScript and forms are not enabled (comment 19 ; comment 20 ; and the new URL of testcase ... you can view this video => http://www.youtube.com/watch?v=3XobLRzLsOk ).

Moz_Bug_R_A4 reported a similar testcase that works on Firefox 8.0 , but with this one , JavaScript and Forms are enabled on the webpage of spoofing (comment 21, phishing testcase2 and phishing testcase3).
Setting to sg:high based on comment 22 and comment 23.
Whiteboard: [sg:high]
Gavin: please find someone on the Firefox team to own this bug. Thanks!
Assignee: nobody → gavin.sharp
Component: General → Tabbed Browser
QA Contact: general → tabbed.browser
The basic setup for the test case is:
- the content document's body onblur has a call to window.alert() in it
- that content window is window.close()d

The sequence of events here is:
- close() triggers the tab removal code (via "DOMWindowClose")
- tabbrowser's _endRemoveTab calls _blurTab, which calls the selectedTab setter (selecting the owner in this case)
- that ends up firing a select event, which triggers updateCurrentBrowser, which updates focus
- the update of focus triggers onblur on the content document, which triggers the alert()
- now the the tabmodal prompts code is triggered, but for a tab that we're still in the process of removing (has already been collapsed). this results in the prompt-with-no-selected tab UI glitch.

From then on, tabbrowser is basically very confused. I haven't tracked down all of the issues, but re-entering tabbrowser code from within _endRemoveTab leads to badness all over the place.

I'm not sure what the best way to fix this is. I think we want to generally avoid showing prompts after tabbrowser decides it's going to be closing the tab, but since it does that in reaction to DOMWindowClose, there isn't currently an easy way to propagate that information back to the window (so that it can throw in response to alert()/prompt() etc.). Maybe we need to add one?
(In reply to Gavin Sharp (use gavin@gavinsharp.com for email) from comment #29)
> From then on, tabbrowser is basically very confused. I haven't tracked down
> all of the issues, but re-entering tabbrowser code from within _endRemoveTab
> leads to badness all over the place.

The main issue in this case is actually that the tabbox selectedIndex setter re-enters itself, since the tab modal prompter triggers DOMWillOpenModalDialog, which in turns sets selectedTab.
Attached patch hacky workaround (obsolete) — Splinter Review
This works around the issue, by refusing to show a prompt for a tab that is closing (I think this breaks beforeunload, so it's not suitable for landing). It also doesn't prevent the prompt early enough to prevent DOMWillOpenModalDialog from firing, so I needed to add a check for closing tabs there too.
Attachment #572254 - Attachment is obsolete: true
Attachment #572419 - Attachment is obsolete: true
Attachment #574020 - Attachment is obsolete: true
Status: NEW → ASSIGNED
OS: Windows 7 → All
Hardware: x86_64 → All
Comment on attachment 577785 [details] [diff] [review]
hacky workaround

>diff -r 95bca70369ef browser/base/content/tabbrowser.xml

>-          this.selectedTab = this._getTabForContentWindow(event.target.top);
>+          let tab = this._getTabForContentWindow(event.target.top);
>+          if (!tab.closing)
>+            this.selectedTab = tab;

Hmm, this change seems to be sufficient for fixing the current testcases, despite not solving the root issue. It's nicely isolated, too, so it might be a suitable workaround for branches.
Gavin, thanks for the awesome summary!

By the time DOMWindowClose is firing have we committed to closing the window/tab?  I mean, beforeunload will still fire after DOMWindowClose and whatnot, but can the window actually say up?
(In reply to Boris Zbarsky (:bz) from comment #33)
> By the time DOMWindowClose is firing have we committed to closing the
> window/tab?  I mean, beforeunload will still fire after DOMWindowClose and
> whatnot, but can the window actually say up?

Not fully... the tabbrowser DOMWindowClose handler doesn't close the tab if:
- there is only one tab left
- the docshell's DocumentViewerImpl::PermitUnload() returns false.
The one tab case also doesn't preventDefault and then we close the window ourselves.

The PermitUnload is worse; that means that a beforeUnload handler can prevent the close.

Adding an explicit way for tabbrowser to tell the window "you're closing now; no more alerts" seems fine to me.
That said, simply removing the <browser> from the DOM should do that now.  Are we calling updateCurrentBrowser before said removal?
(In reply to Boris Zbarsky (:bz) from comment #36)
> That said, simply removing the <browser> from the DOM should do that now. 
> Are we calling updateCurrentBrowser before said removal?

Yes - we update the UI (i.e. collapse the old tab and switch tabs) before removing the <browser>, since apparently that can be slow.
OK, adding a way to notify the window once we have committed to closing it is the simplest approach here, I think.
Attached patch disable dialogs for closing tabs (obsolete) — Splinter Review
I don't understand the current conditional in nsGlobalWindow::AreDialogsBlocked - not sure why it bothers checking the PopupControlState or mDialogAbuseCount - it was preventing me from simply using PreventFurtherDialogs, so I changed it.
Attachment #577785 - Attachment is obsolete: true
Attachment #578105 - Flags: review?(jst)
Attachment #578105 - Flags: feedback?(bzbarsky)
Comment on attachment 578105 [details] [diff] [review]
disable dialogs for closing tabs

Oh, I think I figured out why the check is the way it is - the intent was to presumably only "prevent further dialogs" while the popup blocking state is in effect, so that a window can eventually regain the ability to show dialogs despite PreventFurtherDialogs having been called. I'm not sure how useful that is...
Comment on attachment 578105 [details] [diff] [review]
disable dialogs for closing tabs

General idea seems fine, but I'm not sure about the change to AreDialogsBlocked.  Why not just add another boolean to track this hard block instead?
Attachment #578105 - Flags: feedback?(bzbarsky) → feedback+
Attached patch patch (obsolete) — Splinter Review
Here's a patch with a separate flag. This stuff still seems a little too convoluted...
Attachment #578105 - Attachment is obsolete: true
Attachment #578105 - Flags: review?(jst)
Attachment #578387 - Flags: review?(jst)
Comment on attachment 578387 [details] [diff] [review]
patch

r=jst, and I agree this stuff is a bit convoluted, but that's material for a different bug whenever it's time to clean up here.
Attachment #578387 - Flags: review?(jst) → review+
So one of the side effects of this change is that it fixes bug 391834, for onunload/onpagehide. I noticed this because it triggers a leak in browser_tabview_bug626455.js, which registers three window listeners because it expects three dialogs on tab closing. With this patch it only gets one, so the two other listeners leaked the window.

Given bug 664586, I tend to think we should fix (at least those cases of) bug 391834 anyways, so I think I'll just move my patch there.
(In reply to Gavin Sharp (use gavin@gavinsharp.com for email) from comment #44)
> So one of the side effects of this change is that it fixes bug 391834, for
> onunload/onpagehide.

Although only for the tab closing case, not for other triggers of unload/pagehide (like page navigation). I'll need to find a way to fix that separately.
Attachment #581292 - Attachment mime type: text/plain → text/html
Attachment #581292 - Attachment description: Previous testcase 2.1 for firefox 3.6.X → Previous testcase 1.9 for firefox 3.6.X
We still do need a fix for this. How's it coming in bug 391834?
(In reply to Daniel Veditz [:dveditz] from comment #47)
> We still do need a fix for this. How's it coming in bug 391834?

No progress since my last comments. I don't think we'd want bug 391834 on branches, so I probably need to investigate a more isolated fix here.
Let's track for ESR once this is fixed on mainline.
(In reply to Gavin Sharp (use gavin@gavinsharp.com for email) from comment #48)
> I don't think we'd want bug 391834 on branches, so I probably need
> to investigate a more isolated fix here.

Does it help that we don't have to worry about 1.9.2 anymore? esr10 is the oldest branch, although such a behavior change might be a surprise on an ESR.
Even just fixing it on mainline would be a win. Gavin, how much easier is the world if we just fix trunk?
There are no easy fixes, trunk or otherwise. A variant of attachment 577785 [details] [diff] [review] per comment 32 may be adequate for solving the most pressing issues (it would make some of these testcase "less bad"), but it wouldn't be a complete fix.

I think to address the root causes we need to fix bug 391834, which probably isn't going to happen in the near future (and certainly not on aurora/beta/ESR). I have been meaning to investigate workarounds, but I haven't yet been able to find the time to do so.
Keywords: sec-high
(In reply to :Gavin Sharp (use gavin@gavinsharp.com for email) from comment #53)
> There are no easy fixes, trunk or otherwise. A variant of attachment 577785 [details] [diff] [review]
> [details] [diff] [review] per comment 32 may be adequate for solving the
> most pressing issues (it would make some of these testcase "less bad"), but
> it wouldn't be a complete fix.
> 
> I think to address the root causes we need to fix bug 391834, which probably
> isn't going to happen in the near future (and certainly not on
> aurora/beta/ESR). I have been meaning to investigate workarounds, but I
> haven't yet been able to find the time to do so.

Is there someone else we should ask to do so, in your stead?
Yes, this is on my list of bugs that I need to get fixed.
Assignee: gavin.sharp → nobody
This should have been fixed on trunk by bug 391834.
Looks like that landed in 17, not 16.
Oops, yes, hit the wrong flag. Thanks for catching that.
Status: ASSIGNED → RESOLVED
Closed: 12 years ago
Keywords: verifyme
Resolution: --- → FIXED
Whiteboard: [sg:high] → [sg:high] fixed by bug 391834
Target Milestone: --- → Firefox 17
Is there any reason to believe the situation in Comment 53 has changed at all now that bug 391834 is resolved? We're trying to figure out whether to wontfix for ESR10, and we're getting the feeling this will be first fixed in ESR17.
(In reply to Alex Keybl [:akeybl] from comment #59)
> Is there any reason to believe the situation in Comment 53 has changed at
> all now that bug 391834 is resolved? We're trying to figure out whether to
> wontfix for ESR10, and we're getting the feeling this will be first fixed in
> ESR17.

I think comment 53 is still accurate. We don't want to backport bug 391834 to ESR.
I have reported this vulnerability last year and now there is no fix for this vuln....


Please make a security update for this vulnerability... it's too long...!!!
Attachment #578387 - Attachment is obsolete: true
The fix for bug 391834 is too invasive and risky to take in a security update. This will be fixed in Firefox 17.
with the update , some of old poc are not exploitable (input aren't writable).

This new PoC works very well
Attachment #661832 - Attachment mime type: text/plain → text/html
Jordi: if you're still able to trigger some kind of bad behavior, please file a new bug. It's hard to track multiple issues within one bug, especially when they've already been fixed. File a new bug and refer back to this one.
Confirmed broken on build 2011-11-5, 10.0a1
Verified fixed on build 2012-10-23, 17.0b3
Mac 10.8.2, Windows 7 and Ubuntu 11.10
Status: RESOLVED → VERIFIED
Whiteboard: [sg:high] fixed by bug 391834 → [adv-track-main17+][sg:high] fixed by bug 391834
Whiteboard: [adv-track-main17+][sg:high] fixed by bug 391834 → [adv-track-main17+][sg:high] embargo until EOL ESR10; fixed by bug 391834
Marking this as not tracking for a 17 advisory since it is embargoed until ESR10 EOL.
Alias: CVE-2012-4200
Whiteboard: [adv-track-main17+][sg:high] embargo until EOL ESR10; fixed by bug 391834 → [adv-track-main17-][sg:high] embargo until EOL ESR10; fixed by bug 391834
this bug is fixed on the last update but i don't see my name in an advisory???
Can you reply quickly please?
This is embargoed until ESR10 no longer ships, Jordi. We just shipped the first ESR17. They'll be one more ESR10 release in six weeks. After that, this bug can be discussed in public.
Flags: sec-bounty+
Group: core-security
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: