Last Comment Bug 546909 - (CVE-2010-0178) Firefox should not load chrome URLs dragged from plugins
: Firefox should not load chrome URLs dragged from plugins
: verified1.9.0.19, verified1.9.1, verified1.9.2
Product: Firefox
Classification: Client Software
Component: General (show other bugs)
: unspecified
: All All
: -- normal (vote)
: Firefox 3.7a3
Assigned To: :Gavin Sharp [email:]
Depends on: 551726
  Show dependency treegraph
Reported: 2010-02-18 03:57 PST by Paul Stone
Modified: 2010-07-23 13:50 PDT (History)
14 users (show)
mbeltzner: blocking1.9.0.19-
mbeltzner: wanted1.9.0.x+
See Also:
Crash Signature:
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---

Testcase (561 bytes, text/html)
2010-02-18 04:02 PST, Paul Stone
no flags Details
Background Popup (225 bytes, text/html)
2010-02-21 13:14 PST, Paul Stone
no flags Details
Testcase (v2) (611 bytes, text/html)
2010-02-21 13:31 PST, Paul Stone
no flags Details
patch? (2.92 KB, patch)
2010-02-21 19:37 PST, :Gavin Sharp [email:]
no flags Details | Diff | Review
minimal patch (2.13 KB, patch)
2010-02-21 21:57 PST, :Gavin Sharp [email:]
bzbarsky: review+
Details | Diff | Review
patch using file:/// (2.13 KB, patch)
2010-02-22 15:05 PST, :Gavin Sharp [email:]
dtownsend: review+
mbeltzner: approval1.9.2.2+
Details | Diff | Review
1.9.0/1.9.1 patch (1.95 KB, patch)
2010-03-03 11:18 PST, :Gavin Sharp [email:]
mbeltzner: approval1.9.1.9+
mbeltzner: approval1.9.0.19+
Details | Diff | Review
Debug 1.9.0 showing bug occurring (103.22 KB, image/png)
2010-03-11 10:07 PST, Al Billings [:abillings]
no flags Details
Debug 1.9.1 showing bug occurring (112.79 KB, image/png)
2010-03-11 10:08 PST, Al Billings [:abillings]
no flags Details

Description Paul Stone 2010-02-18 03:57:33 PST
User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)

Firefox will load a chrome:// URL dragged from a Java applet onto the content area.

In a Java applet, the default 'mouse drag gesture recognizer' can be overridden so that a drag operation is initiated as soon as the mouse button is held down. As no mouse movement is required, a drag+drop can be 'forced' by getting the user to click the mouse button, and placing the drop target under the mouse cursor as soon as the drag operation has begun.

I have devised a test case that will allow chrome-privileged JS to be executed by getting the user to perform only three clicks. It works as follows:

1. Open two popup windows, one in front of the other (first click)
2. In the frontmost window, the user is persuaded to click on a Java applet, starting a drag of a chrome URL (any one will do)
3. Once the drag has started, the frontmost window is resized, so that the content area of the other popup window is underneath the mouse cursor.
4. When the drop is completed, the chrome URL loads in the background popup, and the foreground window is resized to it's original size.
5. The user performs another click on the foreground window. This time, a drag of a malicious Javascript URI is initiated.
6. The foreground window is shrunk again and the mouse button is released over the address bar of the background popup window.
7. The Javascript is executed with chrome privs.

I have tested this on Windows XP with the latest Sun Java plugin. It works on both Firefox 3.6 and latest Trunk. I'm not sure if the drag+drop trickery in the Java applet is actually a vulnerability, but Firefox loading a chrome URI definitely is.

Reproducible: Always
Comment 2 Paul Stone 2010-02-18 04:02:03 PST
Created attachment 427575 [details]
Comment 3 Paul Stone 2010-02-18 05:41:28 PST
With a slight modification the same trick can be used to perform XSS on a normal website (without the need for chrome URLs). A site would be loaded into the background popup, then then a Javascript URI dropped onto the address bar. It seems that for non-privileged URLs, javascript and data URIs are not automatically loaded when they are dropped onto the address bar. Therefore, the 'Go' button would need to be clicked. This could be achieved by getting the user to double click something in the foreground window. After the first click, the window would be shrunk and the Go button would be under the cursor.

If a fix was made to Java so that the drag gesture could no longer be overridden, then these same vulnerabilities would remain but would require some more complex interaction from the user (real drag movements would be required instead of just clicks)
Comment 4 Brandon Sterne (:bsterne) 2010-02-18 09:29:49 PST
Interesting.  Dragging a chrome: URL onto a tab works in Windows and Mac, but when I try the same in Linux I get:

Error: uncaught exception: Drop of chrome://browser/content/aboutDialog.xul denied.
Comment 5 Paul Stone 2010-02-18 14:40:57 PST
Brandon, what's the reasoning for rating this as moderate rather than critical?
The bug allows for arbitrary code execution, 'requiring no user interaction
beyond normal browsing'. It also affects the majority of Firefox users (i.e.
those with Java installed). I believe about 80% of web users have Java
installed, I'm not sure what the percentage is for Firefox users. I also don't
think the testcase 'requires the user to perform complicated and/or unlikely
steps', unless you count the three clicks as complicated.
Comment 6 Brandon Sterne (:bsterne) 2010-02-19 10:19:31 PST
I did consider the steps required to exploit this bug as somewhat non-standard.  Seeing the attack window appearing and disappearing would certainly alert me (admittedly, not a typical user) that something weird was happening, and I probably wouldn't be compelled to click the second time, dropping the JS URL on the chrome tab.

What you are saying is perfectly reasonable, though.  If others think the severity should be higher, feel free to make it so.
Comment 7 Lucas Adamski [:ladamski] 2010-02-19 15:50:24 PST
Escalation to chrome: from content is a critical, moderated to high with insufficient reliability of exploit (for example, it doesn't work for me possibly due to my JS settings).  Adjusting to sg:high for now, though I agree that with a really slick exploit it might be even higher.
Comment 10 Paul Stone 2010-02-21 13:31:02 PST
Created attachment 428089 [details]
Testcase (v2)

I've attached a second version that removes the need for the second click in the popup. It turns out that Java allows you to initiate a drag-and-drop without any interaction with the applet at all. The mouse doesn't even have to be over the applet. For some reason this doesn't work for the initial drop onto the content area, but it does work for the second drop onto the address bar.

Lucas, if the example doesn't work for you because you have the 'allow javascript to move and resize windows' option disabled, then I suspect it could be made to work by making the foreground window a Java applet window instead of a Firefox one. It would be possible to detect if window.moveBy and window.resizeBy were disabled and use a Java window instead.
Comment 11 :Gavin Sharp [email:] 2010-02-21 18:03:34 PST
Seems like we should disallow dropping of URI_INHERITS_SECURITY_CONTEXT URIs.
Comment 12 :Gavin Sharp [email:] 2010-02-21 19:37:48 PST
Created attachment 428128 [details] [diff] [review]

This fixes the testcase. I can't think of any use cases for dragging INHERIT_PRINCIPAL URIs that we care to support, really, but maybe I'm missing something.

I had to change this code to deal with the !sourceDoc case, since otherwise this testcase hit it (presumably because the drag comes from Java) and dragDropSecurity check returned early. I'm not sure if there's a better principal to use than about:blank's, for the no-document case.
Comment 13 :Gavin Sharp [email:] 2010-02-21 19:39:20 PST
Note that the DISALLOW_INHERIT_PRINCIPAL change isn't actually needed to fix this - the normal checkLoadURI with sourcePrincipal = about:blank prevents the initial aboutDialog.xul load rather than the second javascript: URI load. So maybe we should just do that and avoid going all the way here.
Comment 14 Boris Zbarsky [:bz] 2010-02-21 21:03:57 PST
I'm not sure why we need or don't (and want or don't) the DISALLOW_INHERIT_PRINCIPAL change yet.  Need to think about it a bit.  Can you explain what the net effect of that change is?

The other difference seems to be that you're switching from checkLoadURIStr to checkLoadURIStrWithPrincipal.  This is obviously a good thing to do, but why does it help in this case?  Or is it just the change to not return early if !sourceDoc that helps with that?  The fact that chrome:// could be loaded like this seems like the real issue here, since the file being changed was supposed to prevent just that.
Comment 15 :Gavin Sharp [email:] 2010-02-21 21:53:44 PST
The part of that patch that fixes the bug is the change to the !sourceDoc case. With the testcase, the dragSession has no source document, so dragDropSecurityCheck was previously a no-op.

The change to the *WithPrincipal version is unrelated cleanup inspired by the deprecation markings in nsIScriptSecurityManager.idl that I figured I'd do while changing the code - it can be omitted, and probably should be for simplicity's sake (we have bug 327244 tracking that anyways).

The addition of DISALLLOW_INHERIT_PRINCIPAL was based on an early guess about a solution, from before I'd looked into the code. It seems reasonable to me to block drags of such URIs in general. That's probably best split off into a separate bug about a more general belt-and-suspenders approach to these kinds of bugs.
Comment 16 :Gavin Sharp [email:] 2010-02-21 21:57:41 PST
Created attachment 428142 [details] [diff] [review]
minimal patch
Comment 17 Boris Zbarsky [:bz] 2010-02-21 21:58:18 PST
I'd prefer a separate bug on that, yeah.  Especially since I drag-n-drop data: URIs a good bit.  Usually from the URL bar to my editor once it gets too unwieldy in the url bar.  ;)

The !sourceDoc change is a clear win in my book.

The WithPrincipal change I'm fine with happening in a different bug, but let's get it actually happening.  The existing code is wrong (in the "won't allow drags that it should" sense) in various cases not dealing with web content, for example.
Comment 18 Mike Beltzner [:beltzner, not reading bugmail] 2010-02-22 10:10:49 PST
This alone wouldn't force a, but should definitely be taken if it's branch-safe for that series.
Comment 19 Mike Beltzner [:beltzner, not reading bugmail] 2010-02-22 10:11:27 PST
Err, it does block, not force a, but wanted on that branch, too. Durr.
Comment 20 :Gavin Sharp [email:] 2010-02-22 13:33:26 PST
(In reply to comment #17)
> I'd prefer a separate bug on that, yeah.  Especially since I drag-n-drop data:
> URIs a good bit.  Usually from the URL bar to my editor once it gets too
> unwieldy in the url bar.  ;)

This check only applies to drops, so the change wouldn't affect that use case, fwiw. I filed bug 547813.
Comment 21 Boris Zbarsky [:bz] 2010-02-22 13:36:46 PST
Hmm.  I thought this check was for the drag start.

So with the attached patch dragging a file:// URI from outside the browser into the browser won't work, right?  That seems suboptimal.
Comment 22 Boris Zbarsky [:bz] 2010-02-22 13:37:27 PST
On the other hand, it's not clear to me that we want to allow a drag from java to allow loading file://, and that's precisely the "from outside the browser" case...
Comment 23 :Gavin Sharp [email:] 2010-02-22 13:50:44 PST
(In reply to comment #21)
> So with the attached patch dragging a file:// URI from outside the browser into
> the browser won't work, right?  That seems suboptimal.

Hmm, indeed :(

I guess there may not currently be a way to differentiate these two cases... So in terms of options for for fixing this testcase, I think that leaves us with pushing for a change in Java (to let us know that the drag is plugin-triggered?), or fixing bug 547813.
Comment 24 :Gavin Sharp [email:] 2010-02-22 13:56:28 PST
(In reply to comment #23)
> or fixing bug 547813.

Though that approach would require that we explicitly check URIChainHasFlags(URI_INHERITS_SECURITY_CONTEXT) rather than relying on checkLoadURI, or change the "from" to be something with the system principal (?).
Comment 25 Boris Zbarsky [:bz] 2010-02-22 13:56:57 PST
Or using file:/// instead of about:blank as the dummy URI, possibly.
Comment 26 :Gavin Sharp [email:] 2010-02-22 14:05:36 PST
(In reply to comment #25)
> Or using file:/// instead of about:blank as the dummy URI, possibly.

Hmm, that's possibly brilliant. My patch with "file:///" rather than about:blank makes file drops work again. Apart from the link-to-file ability, file:/// is the same as about:blank, right? Trying to think of other things this could break.
Comment 27 :Gavin Sharp [email:] 2010-02-22 14:07:16 PST
(It also makes it possible for Java-triggered drag/drops to load file:// URIs as you pointed out, of course, but that's much less of a problem than this bug.)
Comment 28 Boris Zbarsky [:bz] 2010-02-22 14:20:25 PST
> Apart from the link-to-file ability, file:/// is the same as about:blank, right?

For CheckLoadURI purposes, I believe this is correct.
Comment 29 :Gavin Sharp [email:] 2010-02-22 15:05:21 PST
Created attachment 428294 [details] [diff] [review]
patch using file:///
Comment 30 :Gavin Sharp [email:] 2010-02-24 16:49:31 PST
I've given this some thought, and I can't think of any ways that using file:/// as the default origin would break anything important. It will block drops of URI_IS_UI_RESOURCE/URI_DANGEROUS_TO_LOAD URIs that were previously allowed in the drag-from-external-app-or-plugin case, but I don't think there are any valid use cases for that, and we kind of need to prevent those to avoid this bug.

I should probably add a comment about the use of "file:///" as the fallback URI here, though. I'm not sure who else should review this patch...
Comment 31 :Gavin Sharp [email:] 2010-02-25 10:21:06 PST
Comment on attachment 428294 [details] [diff] [review]
patch using file:///

Dave, can you review this with comment 30 in mind?
Comment 32 Dave Townsend [:mossop] 2010-02-25 11:06:03 PST
Comment on attachment 428294 [details] [diff] [review]
patch using file:///

This makes sense to me
Comment 35 Mike Beltzner [:beltzner, not reading bugmail] 2010-02-28 14:01:55 PST
This is reviewed, should it be up for approval?
Comment 39 :Gavin Sharp [email:] 2010-03-01 10:44:39 PST
I landed the patch on the trunk:

I used a cover bug (bug 549349) to try and reduce the likelihood of this being exposed as a security bug before we have it fixed on all branches.

Thanks for the clear report and testcase, Paul!
Comment 40 :Gavin Sharp [email:] 2010-03-01 10:47:49 PST
(In reply to comment #38)
> Gavin, I noticed from my server logs that you were trying the testcase on
> Linux. It doesn't work particularly well there, since an actual drag gesture is
> needed to complete the drop, instead of just a click.

Indeed, I was trying on Linux. I was aware of the drag gesture difference, but in my case the applet was failing to load for some reason. I think the java plugin I'm using is just broken, though.
Comment 41 :Gavin Sharp [email:] 2010-03-03 11:15:33 PST
Comment on attachment 428294 [details] [diff] [review]
patch using file:///

This applies to 1.9.2 cleanly.
Comment 42 :Gavin Sharp [email:] 2010-03-03 11:18:10 PST
Created attachment 430108 [details] [diff] [review]
1.9.0/1.9.1 patch
Comment 43 Mike Beltzner [:beltzner, not reading bugmail] 2010-03-03 12:49:26 PST
Comment on attachment 428294 [details] [diff] [review]
patch using file:///

Comment 44 Mike Beltzner [:beltzner, not reading bugmail] 2010-03-03 14:04:29 PST
Comment on attachment 430108 [details] [diff] [review]
1.9.0/1.9.1 patch

Comment 45 Mike Beltzner [:beltzner, not reading bugmail] 2010-03-05 13:15:58 PST
Can we get this landed? Code freeze is Tuesday, March 9th.
Comment 46 :Gavin Sharp [email:] 2010-03-08 10:32:20 PST
1.9.0: mozilla/toolkit/content/nsDragAndDrop.js 	1.11
Comment 47 :Gavin Sharp [email:] 2010-03-08 10:36:38 PST
Paul: just want to be clear in case you can't make sense of our Bugzilla flag gibberish: this will be fixed in Firefox 3.0.19, 3.5.9, and 3.6.2 which are all due out shortly. Thanks again!
Comment 48 Al Billings [:abillings] 2010-03-10 17:11:56 PST
I see the same behavior in and my personal debug build of on Windows XP SP2. The same goes for and using the attached testcase.

I wind up, eventually, with an alert stating "JS frame :: javascript:alert(Components.stack) :: <TOP_LEVEL> :: line 1" in both instances over a windows loaded from the about firefox chrome as a window after doing the whole "click me" routine on the applet.

This appears fixed for though with Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20100310 Namoroka/3.6.2pre (.NET CLR 3.5.30729) on the same machine. Clicking on the "click me" app does not launch a chrome window.

So, 1.9.0 and 1.9.1 are *not* fixed unless I'm missing something.
Comment 49 Mike Beltzner [:beltzner, not reading bugmail] 2010-03-10 17:17:46 PST
Paul, can we get you to test the builds for us and let us know if they're fixed for you? You can get them here:

Comment 50 Al Billings [:abillings] 2010-03-10 17:21:47 PST
Was the 1.9.0 and 1.9.1 version of this patch code reviewed? I don't see a reviewer above or was it close enough to the 1.9.2 patch that it didn't matter (though comment 48 might argue against that)?
Comment 51 Mike Beltzner [:beltzner, not reading bugmail] 2010-03-10 21:25:36 PST
Mossop - you reviewed the original patch. Is the 1.9.0/1.9.1 patch a straight port? I didn't notice the lack of review, and the code looks pretty much the same to me. Gavin's out on vacation otherwise I'd be asking him.
Comment 52 Mike Beltzner [:beltzner, not reading bugmail] 2010-03-11 05:23:41 PST
(Removing fixed flags for the versions in which Al claims this is not fixed)
Comment 53 Neil Deakin 2010-03-11 06:23:56 PST
The 1.9.0/1.9.1 is functionally the same. The only difference is that a few lines are moved around due to other changes.
Comment 54 Paul Stone 2010-03-11 07:28:19 PST
I've tested all three builds that Mike linked to and all are indeed fixed. I tested them on Windows XP SP2, as Al did.
Comment 55 Mike Beltzner [:beltzner, not reading bugmail] 2010-03-11 07:37:38 PST
Thanks, Paul. Re-marking as FIXED. Al, back to you to verify, maybe use the nightly builds instead of your own local ones?
Comment 56 Al Billings [:abillings] 2010-03-11 08:30:50 PST
I'll check again. The only thing unusual about the builds I was using yesterday is that they were debug builds. I saw no difference in pre and post-fix functionality (each wound up with an alert stating "JS frame ::
javascript:alert(Components.stack) :: <TOP_LEVEL> :: line 1") for 1.9.0 and 1.9.1. This was *not* the case with 1.9.2.

Paul, is the expect behavior that one does *not* get this alert after repeatedly clicking on the "click me" applet?
Comment 57 Paul Stone 2010-03-11 08:36:31 PST
Al, that's correct. The 'About Firefox' page shouldn't load, and there shouldn't be any alert.
Comment 58 Al Billings [:abillings] 2010-03-11 10:07:27 PST
Created attachment 431907 [details]
Debug 1.9.0 showing bug occurring

This is my debug build from 3/10/2010. This shows that the testcase still repros in debug. 

In the non-debug nightly on the same machine, the bug is fixed and I never get the chrome window or the alert. That build is Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/2010031005 GranParadiso/3.0.19pre (.NET CLR 3.5.30729).
Comment 59 Al Billings [:abillings] 2010-03-11 10:08:52 PST
Created attachment 431908 [details]
Debug 1.9.1 showing bug occurring

This is a screenshot from my 1.9.1 debug build from 3/10/2010, showing the bug still occurring with the testcase.

When I use the non-debug 1.9.1 nightly build, the case no longer reproduces. That build is Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20100310 Shiretoko/3.5.9pre (.NET CLR 3.5.30729).
Comment 60 Al Billings [:abillings] 2010-03-11 10:10:51 PST
So, Paul is correct in that the non-debug builds will no longer reproduce the bug. My debug builds still do reproduce them and I synched and built them around noon on 3/10/2010 so they have the fix's code. 

I'm not sure if I should mark this as verified fixed for 1.9.0 and 1.9.1 when it still reproduces in debug. I will let Dan Veditz and Mike Beltzner tell me what we want to do here.
Comment 61 Mike Beltzner [:beltzner, not reading bugmail] 2010-03-11 10:30:28 PST
File a new bug about how the debug builds still trip the behaviour, mark it as blocking this one.
Comment 62 Boris Zbarsky [:bz] 2010-03-11 10:33:06 PST
Al, just to double-check what are the changeset IDs (or even just the URIs) your debug builds list in about:buildconfig ?
Comment 63 Al Billings [:abillings] 2010-03-11 10:39:54 PST
Ah crap, my VM blows. I did a rollback and didn't pick up changes so I have pre-fix code. This is my mistake.

I'll go fix my builds now.
Comment 64 chris hofmann 2010-03-20 17:37:08 PDT

If you are interested you are eligible or a security bug bounty on this bug.  You can you contact me at about the bounty.

Note You need to log in before you can comment on or make changes to this bug.