Closed
Bug 616659
(CVE-2011-0051)
Opened 14 years ago
Closed 14 years ago
Recursing the JavaScript eval function over itself eventually causes all dialogs with confirmation to evaluate to "true".
Categories
(Core :: DOM: Core & HTML, defect)
Core
DOM: Core & HTML
Tracking
()
People
(Reporter: zrhoffman, Assigned: smaug)
Details
(Keywords: reporter-external, verified1.9.1, verified1.9.2, Whiteboard: [sg:critical] [qa-ntd-191])
Attachments
(2 files)
854 bytes,
patch
|
jst
:
review+
|
Details | Diff | Splinter Review |
989 bytes,
patch
|
Dolske
:
review+
Gavin
:
review+
christian
:
approval1.9.2.14+
christian
:
approval1.9.1.17+
|
Details | Diff | Splinter Review |
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-us) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5
Build Identifier: http://www.mozilla.com/en-US/products/download.html?product=firefox-3.6.12&os=win&lang=en-US
Obviously, code like eval(a="eval(a)") causes the script to error out. But adding a try/catch block like eval(a="try{eval(a)}catch(b){/*code here*/}") lets you catch the "eval'd-out" state and execute code in it. Any dialog box opened in this state instead shows a textless dialog box with two textless buttons, and pressing these buttons does not close this box. Closing the box with the corner "X" button causes input boxes (confirm, onbeforeunload, netscape.security.PrivilegeManager.enablePrivilege, etc.) to evaluate to "true".
Reproducible: Always
Steps to Reproduce:
The following code will open a dialog: eval(a="try{eval(a)}catch(b){c=confirm('You will not see this text')}")
Actual Results:
In Windows 7, the only immediate way to close the aforementioned dialog is by pressing the "X" corner button. If the user performs this action, Firefox will proceed as if the user pressed "OK", causing c == true.
Expected Results:
In a normal case, this action is the equivalent of pressing "Cancel", meaning c == false.
See the attachment in the comments for an example that uses this vulnerability for arbitrary code execution.
Reporter | ||
Comment 1•14 years ago
|
||
Because this example uses netscape.security.PrivilegeManager.enablePrivilege, an on-the-Web version would be just as dangerous but would probably need to be placed inside a signed script JAR. To avoid this complexity, I'm assuming that you know to run it locally.
Updated•14 years ago
|
Component: General → DOM: Core & HTML
Product: Firefox → Core
QA Contact: general → general
Hardware: x86 → All
Updated•14 years ago
|
blocking1.9.1: --- → ?
blocking1.9.2: --- → ?
blocking2.0: --- → ?
status1.9.1:
--- → ?
status1.9.2:
--- → ?
Reporter | ||
Comment 2•14 years ago
|
||
As before, run locally on Windows. Clicking the button causes a textless dialog to pop up. "X"-ing out the dialog opens C:\WINDOWS\system32\calc.exe.
Updated•14 years ago
|
Status: UNCONFIRMED → NEW
blocking1.9.1: ? → .17+
blocking1.9.2: ? → .14+
Ever confirmed: true
Whiteboard: [sg:critical]
Comment 4•14 years ago
|
||
On Mac we use "sheets" rather than dialogs -- there is no 'X' to dismiss. You end up unable to switch tabs or do much of anything and must force-quit (arguably better than letting the attack succeed). I expect the attack to succeed on Linux but have not tried it (of course the testcase must be modified).
I tried Minefield on windows and did not get the testcase to work. The dialog never came up and eventually I got a security exception about file:/// trying to get UniversalXPConnect privs. I don't think we changed anything with enablePrivilege so maybe we changed something in the JS engine or DOM that causes the attack to fail (the dialogs return false/cancel when they can't be created?). The attack definitely succeeds on Windows in both 3.5.x and 3.6.x
Updated•14 years ago
|
blocking2.0: ? → betaN+
Assignee | ||
Comment 6•14 years ago
|
||
On 3.6 linux the browser just enters to an endless loop
and gives "JavaScript error: , line 0: too much recursion"
There are no dialogs.
Assignee | ||
Comment 7•14 years ago
|
||
So how do I get the "sheet" on OSX?
I run the test locally, and still just get endless loop or something.
No dialogs, no "sheets".
Comment 8•14 years ago
|
||
When I ran the testcase on OSX I saw just the very beginning of the "sheet" which was just a square a few pixels wide right below the location bar. It was window-modal, though, in the sense that my menus were disabled and I couldn't switch to any other tab.
Assignee | ||
Comment 9•14 years ago
|
||
Ah, ok. I think I see something similar on OSX.
Assignee | ||
Comment 10•14 years ago
|
||
I don't have Windows development setup, and can't reproduce the problem on Linux
and on OSX the problem is not critical if I understand this right.
But here is a patch which might help.
Based on the code and the error I get on Linux this could help.
Anyone willing to try? The fix is for netscape.security.PrivilegeManager.enablePrivilege() -like prompts.
Assignee | ||
Updated•14 years ago
|
Status: NEW → ASSIGNED
Assignee | ||
Comment 11•14 years ago
|
||
Comment on attachment 496170 [details] [diff] [review]
fix?
OK, this fixes the critical part of the bug.
Similar thing could be added to other dialogs.
Attachment #496170 -
Flags: review?(jst)
Assignee | ||
Comment 12•14 years ago
|
||
(In reply to comment #4)
> I tried Minefield on windows and did not get the testcase to work. The dialog
> never came up and eventually I got a security exception about file:/// trying
> to get UniversalXPConnect privs. I don't think we changed anything with
> enablePrivilege so maybe we changed something in the JS engine or DOM that
> causes the attack to fail (the dialogs return false/cancel when they can't be
> created?). The attack definitely succeeds on Windows in both 3.5.x and 3.6.x
Prompt handling was rewritten for FF4.
Assignee | ||
Comment 13•14 years ago
|
||
So I could still clarify that the code where the bug is, has been removed in FF4.
Comment 14•14 years ago
|
||
What exactly is the patch fixing? eButtonPressed isn't checked by other code, and commonDialog.js's commonDialogOnload() should be initializing it already... Is this bug somehow causing a code path that avoids the initialization?
Comment 15•14 years ago
|
||
(In reply to comment #14)
> What exactly is the patch fixing? eButtonPressed isn't checked by other code,
> and commonDialog.js's commonDialogOnload() should be initializing it already...
> Is this bug somehow causing a code path that avoids the initialization?
By the time that we try to call into commonDialog.js, we're already basically out of C stack space to run JS in, so we probably throw trying to even call into that code. However, given what a mess all of the dialog/window code is, we probably lose the fact that we failed to run the JS somewhere and continue on as if we had.
Updated•14 years ago
|
Attachment #496170 -
Flags: review?(jst) → review+
Assignee | ||
Updated•14 years ago
|
Attachment #496170 -
Flags: approval1.9.2.14?
Attachment #496170 -
Flags: approval1.9.1.17?
Comment 16•14 years ago
|
||
Ah, I guess that makes sense. Mildly surprising there isn't an error being returned back from OpenWindow(), we still use that code path so it would kinda be nice to figure out where the fail is being dropped.
But this workaround seems fine. You could fix all the prompts for free by having nsPromptService::DoDialog() just do aParamBlock->SetInt(eButtonPressed, 1). Unconditionally setting this should be fine. [IE, basically do the initialization commonDialog.js was doing.]
Comment 17•14 years ago
|
||
(In reply to comment #16)
> Ah, I guess that makes sense. Mildly surprising there isn't an error being
> returned back from OpenWindow(), we still use that code path so it would kinda
> be nice to figure out where the fail is being dropped.
This is total speculation, but I assume that we run JS while loading the XUL for the dialog's window. That would mean that the error actually gets thrown into a nested event loop run by nsWindowWatcher::OpenWindowJSInternal and gets lost there.
Assignee | ||
Comment 18•14 years ago
|
||
(In reply to comment #16)
> You could fix all the prompts for free by
> having nsPromptService::DoDialog() just do aParamBlock->SetInt(eButtonPressed,
> 1). Unconditionally setting this should be fine. [IE, basically do the
> initialization commonDialog.js was doing.]
Yeah, could probably do that.
Assignee | ||
Comment 19•14 years ago
|
||
Attachment #498119 -
Flags: review?(dolske)
Attachment #498119 -
Flags: approval1.9.2.14?
Attachment #498119 -
Flags: approval1.9.1.17?
Assignee | ||
Updated•14 years ago
|
Attachment #496170 -
Flags: approval1.9.2.14?
Attachment #496170 -
Flags: approval1.9.1.17?
Assignee | ||
Comment 20•14 years ago
|
||
Dolske, review ping.
Comment 21•14 years ago
|
||
Waiting on review to approve.
Comment 22•14 years ago
|
||
Comment on attachment 498119 [details] [diff] [review]
v2
Would be good to add a "Default to 'Cancel'" comment.
Attachment #498119 -
Flags: review+
Assignee | ||
Comment 23•14 years ago
|
||
Sure. I'll add that before pushing.
Updated•14 years ago
|
Attachment #498119 -
Flags: review?(dolske) → review+
Comment 24•14 years ago
|
||
Comment on attachment 498119 [details] [diff] [review]
v2
Approved for 1.9.2.14 and 1.9.1.17
Attachment #498119 -
Flags: approval1.9.2.14?
Attachment #498119 -
Flags: approval1.9.2.14+
Attachment #498119 -
Flags: approval1.9.1.17?
Attachment #498119 -
Flags: approval1.9.1.17+
Assignee | ||
Comment 25•14 years ago
|
||
http://hg.mozilla.org/releases/mozilla-1.9.1/rev/4a116f8706b7
http://hg.mozilla.org/releases/mozilla-1.9.2/rev/d8c58cf0e7a5
Status: ASSIGNED → RESOLVED
Closed: 14 years ago
Resolution: --- → FIXED
Comment 26•14 years ago
|
||
I don't think that I'd call this fixed. I verified the problem with 1.9.2.13 and then tried the nightly .14pre build on XP. The PoC's no longer launch calculator after the fix but the browser is still completely unusable. The user winds up with an Internet Security dialog with two blank buttons that cannot be closed. See http://img84.imageshack.us/img84/8548/screenshot20110104at153.png.
The only way out is to kill the entire Firefox process. Does a DoS count as fixed? :-)
Loading both of the PoC's on 1.9.1.16, as soon as the user clicks on the "clicky" button, the whole browser loses focus and cannot be closed (I can't see focus going anywhere but the main window cannot get it back). The only solution is to kill the process. No calculator is launched but the browser is unusable. Post-fix on 1.9.1.17pre, the behavior is exactly the same.
This appears to need some more work.
Assignee | ||
Comment 27•14 years ago
|
||
I was fixing the sg:critical part of the bug. The DoS part is something quite different.
Comment 28•14 years ago
|
||
So I can call this "verified" for 1.9.2 since calculator doesn't launch?
Pre-fix on 1.9.1, it never launches calculator and the pre and post-fix behavior is the same. I'm not sure what to verify there.
Comment 29•14 years ago
|
||
> So I can call this "verified" for 1.9.2 since calculator doesn't launch?
that sounds right once you get to a state like Dan had in comment 4 where he was able to recreate on 1.9.1 and 2.
and maybe open a new bug for the sg:dos part?
Comment 30•14 years ago
|
||
I haven't been able to duplicate Dan's state in comment 4. Dan, any comments or suggestions? Have you been able to duplicate it again?
Updated•14 years ago
|
Status: RESOLVED → UNCONFIRMED
status1.9.1:
.17-fixed → ---
status1.9.2:
.14-fixed → ---
Ever confirmed: false
Resolution: FIXED → ---
Comment 31•14 years ago
|
||
What exactly is left here for trunk?
Assignee | ||
Comment 32•14 years ago
|
||
The code where the sg:crit bug is, has been removed in the trunk.
Assignee | ||
Comment 33•14 years ago
|
||
Gavin, why did you change this to UNCONFIRMED? And removed also 1.9.1 and 1.9.2 status flags?
Assignee | ||
Comment 34•14 years ago
|
||
Changing back to fixed.
Status: UNCONFIRMED → RESOLVED
Closed: 14 years ago → 14 years ago
status1.9.1:
--- → .17-fixed
status1.9.2:
--- → .14-fixed
Resolution: --- → FIXED
Comment 35•14 years ago
|
||
Sorry, just a mistake (didn't reload hard enough).
Comment 36•14 years ago
|
||
Marking verified for 1.9.2. Since the problem doesn't manifest with the PoC on 1.9.1, I can't verify the fix there.
Keywords: verified1.9.2
Whiteboard: [sg:critical] → [sg:critical] [qa-ntd-191]
Reporter | ||
Comment 37•14 years ago
|
||
Apparently, in 1.9.1 the browser's behavior varies depending on whether any dialogs have been shown during the current session but prior to the attack. This example displays a dialog before continuing, which probably causes it to succeed for the entire 1.9.1 branch.
Comment 38•14 years ago
|
||
Using the new testcase 3, I've verified calculator launching pre-fix and being fixed in the current 1.9.1 nightly (Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.17pre) Gecko/20110118 Shiretoko/3.5.17pre ( .NET CLR 3.5.30729)).
Keywords: verified1.9.1
Updated•14 years ago
|
Alias: CVE-2011-0051
Updated•14 years ago
|
Group: core-security
Updated•12 years ago
|
Flags: sec-bounty+
Updated•9 months ago
|
Keywords: reporter-external
You need to log in
before you can comment on or make changes to this bug.
Description
•