Last Comment Bug 298255 - Stand-alone applications can run arbitrary code through Firefox
: Stand-alone applications can run arbitrary code through Firefox
Status: RESOLVED FIXED
[sg:fix] Bug details embargoed until ...
: fixed-aviary1.0.5
Product: Core
Classification: Components
Component: Security (show other bugs)
: Trunk
: All All
: -- critical (vote)
: ---
Assigned To: Daniel Veditz [:dveditz]
:
: David Keeler [:keeler] (use needinfo?)
Mentors:
Depends on: 310793 300800
Blocks: 299444 300114
  Show dependency treegraph
 
Reported: 2005-06-20 09:36 PDT by Michael Krax
Modified: 2007-04-01 15:10 PDT (History)
15 users (show)
dveditz: blocking1.7.9+
dveditz: blocking‑aviary1.0.5+
dveditz: blocking1.8b3+
bob: in‑testsuite?
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
Testcase for automated exploit using Quicktime and Flash (19.68 KB, application/octet-stream)
2005-06-27 05:47 PDT, Michael Krax
no flags Details
aviary 1.0.x patch (11.48 KB, patch)
2005-07-06 02:59 PDT, Daniel Veditz [:dveditz]
no flags Details | Diff | Splinter Review
incorporating mconnor's suggestions (11.56 KB, patch)
2005-07-06 05:14 PDT, Daniel Veditz [:dveditz]
mconnor: review+
jst: superreview+
chofmann: approval‑aviary1.0.5+
chofmann: approval1.7.9+
Details | Diff | Splinter Review
trunk version (incl suite) (14.87 KB, patch)
2005-07-06 16:39 PDT, Daniel Veditz [:dveditz]
mconnor: review+
dveditz: superreview+
dveditz: approval1.8b3+
Details | Diff | Splinter Review
xpfe chrome blocker for branch and probably trunk too (3.02 KB, patch)
2005-07-07 03:50 PDT, neil@parkwaycc.co.uk
no flags Details | Diff | Splinter Review

Description Michael Krax 2005-06-20 09:36:02 PDT
User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4

Most media types that can be viewed in Firefox using an embedded plugin, can
also be viewed in a stand-alone application. This applies to the most common
audio/video media types like ram/rpm/wmv/mov/avi, document formats like pdf and
multimedia formats like swf (flash). 

The stand-alone programms can (as every other desktop application) open URLs in
Firefox, usually be passing the URL to the operation system and invoking the
standard browser. The URL calls are (unlike when embedded) not checked at all. A
stand-alone mediaplayer can open chrome: and javascript: urls.

While this is expected behavior, it turns into a security risk when looking at
the fact, that it is easy to force that a media file gets opened in the stand
alone programm instead of embedding it. Usually it is enough to set
Content-Disposition header to type "attachement". This will result in a file
download dialog which most people will accept, since many websites use this as a
valid feature (e.g. for pdf downloads). Some video players (e.g. Quicktime)
support dedicated formats to force that a video gets played in the stand-alone
player - mostly due the fact that only the stand-alone quicktime player supports
real fullscreen playback. 

The problem is, that many media container formats (e.g. smil) and most
multimedia formats (e.g. swf) allow to automaticly open URLs by several
scripting languages or other mechanisms. That means scripting commands coming
from an untrusted source can automaticly invoke a desktop programm and then
re-invoke Firefox to run arbitrary code by opening a chrome: url and then a
javascript: url (to get universal xpconnect). 

One could argue, that this is a problem of the media players, but the media
players are (usually) secure in handling the various containers formats - they
just assume it is safe to throw urls of any kind at the default operation system
webbrowser. And in case of Firefox, it's not.

To proof this theory, i looked at the various file formats and players. I found
a reproducable way in the handling of stand-alone flash (swf) files. The
following peace of action script could be used to run arbitrary code from an swf
file in a stand alone player:

SWFAction("a=this.geturl('chrome://browser/content/browser.xul');b=this.geturl('javascript:alert(document.location);');"));

There are some timing issues with this demo (when the xul page loads too slow)
you usally have to try 2-3 times and re-start the browser after each try. I am
not so good in flash, there are probably ways to make that more stable. The good
news is, that flash does not ship with a stand-alone player by default, it only
comes with the flash development environment or from third partys. Anyway, bad
news is that it proofs the theory.

Another proven way to open a chrome url is the quicktime player (using <a href>
in a smil file) - and since the number of ways to manually and automaticly open
URLs from media formats are literally endless (real, windows media, quicktime
all support multiple ways of 'in-stream' url encodings, smil supports timed
hyperlink events, acrobat reader supports javascript, etc) i strongly believe
that there are many more ways.

Is there any valid use for desktop applications invoking a chrome file and/or
opening a javascript url in the context of another website? Shouldn't it be safe
to throw URLs at Firefox in any order - especially when considering that many
third party developers don't know about privileged xul? 

Reproducible: Always
Comment 1 Michael Krax 2005-06-27 05:47:31 PDT
Created attachment 187396 [details]
Testcase for automated exploit using Quicktime and Flash
Comment 2 Michael Krax 2005-06-27 05:56:53 PDT
It seems nobody takes care of this right now - still unconfirmed after a week.

I added a test case that shows an automated exploit of this bug. As described in
my initial post formats like QuickTime can automaticly open the stand-alone
player from within an embedded browser - it only requires a special target
property called "quicktimeplayer". The QuickTime player can run SWF files and
those can open chrome: and javascript: urls. Putting all this together you get a
fully running exploit.

The demo still has some timing issues, but should work properly in about 40% of
the attempts. Tried that on three different machines. Restart the browser and
close Quicktime after a failed attempt.

Raising the severity to critical since it's now fully working remote code execution.
Comment 3 Daniel Veditz [:dveditz] 2005-06-28 04:10:54 PDT
This is doing something other than the normal opening a URL from an external
application. When opened from the OS each URL is going to get a new window (or
tab depending on pref settings), and in that situation the context for
javascript urls will be the harmless about:blank rather than the previous chrome
url.

This testcase demonstrates that's not the case. Are these URLs opened through
the plugin interface? I thought bug 280664 stopped the loading of chrome: from
plugins?
Comment 4 Michael Krax 2005-06-28 04:25:17 PDT
(In reply to comment #3)
> This is doing something other than the normal opening a URL from an external
> application. When opened from the OS each URL is going to get a new window (or
> tab depending on pref settings)

Not every time. Using flash you can open two urls more or less at the same
moment and that results in opening them in the same browser window (maybe just a
timing issue). Other browser (e.g. IE) do open two new windows.

Some other applications are at least able to open one url in an exesting window
- usually the currently active window/tab - this would lead to cross domain
scripting (e.g. to steal cookies):

1. Open the stand-alone quicktime player
2. Do a javascript location.replace to "target.domain" in the opening page
3. Invoke the existing window with a javascript: url in the context of
"target.domain"

This seems to be a window naming thing (e.g. it works when clicking a link in an
external application which targets "_parent"). It only works the first time.
After that you always open new windows unless you restart the browser.

> This testcase demonstrates that's not the case. Are these URLs opened through
> the plugin interface? I thought bug 280664 stopped the loading of chrome: from
> plugins?

When you play the SWF file in an embedded player, the patch for 280664 kicks in.
But in this case the OpenURL commands comes from the stand-alone player /
operation system and circumvents it.
Comment 5 Daniel Veditz [:dveditz] 2005-06-28 05:04:51 PDT
(In reply to comment #3)
> This is doing something other than the normal opening a URL from an external
> application. When opened from the OS each URL is going to get a new window
> (or tab depending on pref settings)

True for the trunk: the pref browser.link.open_external is set to 3 in Firefox
(new tab) and 2 in Suite (new window). But on the aviary/1.7 branches it was set
to 1 -- reuse the currently open window.

I always seem to get the JS url to open first so I don't quite see the exploit,
but I imagine it would be trivial to put a delay in the flash script to make
sure the chrome URL has opened first. In any case a javascript URL could be used
to steal information from the currently opened page.

What if we do something like the solution to the history.back() bug and
explicitly load about:blank first to clear the plate when loading an external URL?
Comment 6 Daniel Veditz [:dveditz] 2005-06-29 07:49:46 PDT
In addition to putting a context-clearing about:blank load in front of any
javascript: or data: url, there's no need to allow chrome: urls to be loaded
into a browser window from external programs at all. People who have built
non-browser chrome applications launch them with "-chrome
chrome:/mychrome/content/", not "-url chrome:/mychrome/content/"
Comment 7 Johnny Stenback (:jst, jst@mozilla.com) 2005-06-29 15:25:51 PDT
Yeah, sounds reasonable to me. Should be pretty easy to do, even. You hacking on
this dveditz?
Comment 8 Daniel Veditz [:dveditz] 2005-06-30 13:48:01 PDT
This is a Suite issue as well.
Comment 9 Daniel Veditz [:dveditz] 2005-07-06 02:59:21 PDT
Created attachment 188417 [details] [diff] [review]
aviary 1.0.x patch

This works for aviary.
Comment 10 Daniel Veditz [:dveditz] 2005-07-06 05:14:24 PDT
Created attachment 188423 [details] [diff] [review]
incorporating mconnor's suggestions
Comment 11 Mike Connor [:mconnor] 2005-07-06 05:40:17 PDT
Comment on attachment 188423 [details] [diff] [review]
incorporating mconnor's suggestions

>+  try {
>+    if (makeURL(uriToLoad).schemeIs("chrome")) {
>+      dump("Preventing external load of chrome: URI\n");

lets go a step farther and add "To load chrome URIs, you must use the -chrome
switch.\n" here

>-                     .loadURI(url, nsIWebNavigation.LOAD_FLAGS_NONE, referrer,
>+                     .loadURI(url, loadflags, referrer,
>                               null, null);

nit: there's no need for the args to be split onto two lines now, you fixed
this in the previous case

>+    // Before going any further vet loads initiated by external programs.
>+    if (aLoadType == LOAD_NORMAL_EXTERNAL) {
>+        // clear the decks to prevent context bleed-through (bug 298255)
>+        rv = CreateAboutBlankContentViewer();

shouldn't you be checking rv here?

>+        // Disallow external chrome: loads targetted at content windows
>+        PRBool isChrome = PR_FALSE;
>+        if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome) {
>+            return NS_ERROR_FAILURE;
>+        }

this should probably go before the previous block, since there's no point in
creating the new content viewer if we're going to fail here

r=me with those
Comment 12 Johnny Stenback (:jst, jst@mozilla.com) 2005-07-06 08:12:26 PDT
Comment on attachment 188423 [details] [diff] [review]
incorporating mconnor's suggestions

sr=jst
Comment 13 chris hofmann 2005-07-06 09:57:00 PDT
Comment on attachment 188423 [details] [diff] [review]
incorporating mconnor's suggestions

a=chofmann for the branches
Comment 14 Daniel Veditz [:dveditz] 2005-07-06 10:46:28 PDT
Landed on aviary branch
Comment 15 Daniel Veditz [:dveditz] 2005-07-06 16:39:48 PDT
Created attachment 188483 [details] [diff] [review]
trunk version (incl suite)

Seeking Neil's r= on the navigator.js portion which was not reviewed as part of
the aviary branch patch
Comment 16 Jay Patel [:jay] 2005-07-06 19:03:04 PDT
v.fixed on aviary with Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.9)
Gecko/20050706 Firefox/1.0.5.

Still waiting to land on the Trunk and 1.7 branch, where it will need to be
verified as well.
Comment 17 Mike Connor [:mconnor] 2005-07-06 22:44:17 PDT
Comment on attachment 188483 [details] [diff] [review]
trunk version (incl suite)

r=mconnor
Comment 18 Daniel Veditz [:dveditz] 2005-07-07 02:16:28 PDT
Not quite sure what to do about mozilla 1.7.x. This fix builds on the
nsIBrowserDOMWindow::OPEN_EXTERNAL stuff that was added to aviary but not the
suite until sometime on the trunk.
Comment 19 Daniel Veditz [:dveditz] 2005-07-07 03:11:31 PDT
Fix checked into trunk. Neil has some concerns that this blocks the ability to
have a chrome: home page and is working on an alternate patch for the "startup"
part of this.

That approach will also work for the 1.7 branch to prevent loading chrome urls
from external, but not solve the javascript: problem unless we're ok just
blocking those outright.
Comment 20 neil@parkwaycc.co.uk 2005-07-07 03:50:50 PDT
Created attachment 188529 [details] [diff] [review]
xpfe chrome blocker for branch and probably trunk too
Comment 21 Christian :Biesinger (don't email me, ping me on IRC) 2005-07-07 04:38:09 PDT
+    if (makeURL(uriToLoad).schemeIs("chrome")) {

is that sufficient? For example, about:config also has chrome privileges. is
that taken care of by the other checks?
Comment 22 neil@parkwaycc.co.uk 2005-07-08 16:56:33 PDT
Actually it turns out that suite already (tries to, but my Windows doesn't
recognise it) associate external chrome: URLs with the -chrome option.
Comment 23 Daniel Veditz [:dveditz] 2005-07-12 11:35:02 PDT
Adding distributors
Comment 24 Daniel Veditz [:dveditz] 2005-07-12 17:59:37 PDT
Suite 1.7 is OK on this one: the default behavior is to open external links in
new windows so javascript: urls are always run in an about:blank context. The
trunk version of the suite has the option to reuse the most recent window (still
not the default), but the context-clearing fix landed on the trunk.
Comment 25 Boris Zbarsky [:bz] (still a bit busy) 2005-07-14 11:33:20 PDT
Filed bug 300800 on some issues I think that patch has...
Comment 26 Brendan Eich [:brendan] 2005-07-17 10:27:51 PDT
Looks like the fix to this bug caused bug 301073.

/be
Comment 27 neil@parkwaycc.co.uk 2005-07-17 12:53:21 PDT
Comment on attachment 188483 [details] [diff] [review]
trunk version (incl suite)

Mozilla/Suite uses -chrome for chrome:// URL protocol so I claim it doesn't
need the startup patch so please back it out to fix the xpfe version of bug
301073.
Comment 28 Jesse Ruderman 2005-09-02 03:55:04 PDT
More followups: bug 305374, bug 305269, bug 304690.

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