Bug 410156 (CVE-2008-2810)

URL files (IE bookmarks) cause remote code to run as local file when opened directly

RESOLVED FIXED in Firefox 3

Status

()

Firefox
Security
P2
normal
RESOLVED FIXED
10 years ago
5 months ago

People

(Reporter: Fedge, Assigned: rstrong)

Tracking

({verified1.8.1.15})

Trunk
Firefox 3
x86
Windows XP
verified1.8.1.15
Points:
---
Bug Flags:
blocking-firefox3 +
blocking1.8.1.15 +
wanted1.8.1.x +
blocking1.8.0.next +
in-testsuite +

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [sg:moderate])

Attachments

(3 attachments, 2 obsolete attachments)

(Reporter)

Description

10 years ago
User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9b3pre) Gecko/2007122805 Minefield/3.0b3pre
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9b3pre) Gecko/2007122805 Minefield/3.0b3pre

I added Firefox to my Send To: menu to allow me to open local HTML and URL files in Firefox because these extensions are associated with my editors.

I opened a URL file from my IE favorites folder this way (equivalent of dragging it onto the Firefox executable) and lo and behold, the page loaded as a file: protocol page but then went on to download the HTML from the remote server! This should cause a redirect to the URL embedded in the file rather than running it as a local file containing 100% remote code. I'm sure there's > 20 exploits that could be done after this stage has been reached, including spidering the HD through an iframe and sending the data back via dynamic script tag with relative URL added to the page's code.

Reproducible: Always

Steps to Reproduce:
1. Add Firefox to Send To menu
2. Send it a URL file

Actual Results:  
Remote code loaded under the file: protocol

Expected Results:  
Remote page URL in the address bar, then page load.
How was it 100% remote code? what was in the local file itself then?
(Reporter)

Comment 2

10 years ago
URL files only contain a URL, the idea is that a browser loads the file and reads the URL then goes to the page specified by the URL in the file.

Internet Explorer shortcuts (favorites) are stored in files with a .url extension.

Windows typically hides the .url extension from users even if the option to show file extensions is specified in the folder options, similar to the way .lnk and .pif files are treated so that's why you have never seen this file extension or investigated this type.

Here's a description of the format:

http://www.cyanwerks.com/file-format-url.html
Sorry for the holiday-induced delay. Confirming bug.

I was fooled by the statement "equivalent of dragging it onto the Firefox executable" and was dropping the favorite onto an open browser window. That works fine, the correct site is opened. But right-clicking on the .url shortcut and choosing SendTo, or dragging it onto the Firefox _shortcut_ icon behaves as described: remote content is loaded as a file: uri (so all relative URIs on the page are broken). Ugly if it's content you want, absolutely no protection from evil content in-line or loaded from absolute URIs.

On the trunk the file access changes prevent this from being more than a minor security problem, it's just a bug. But FF2 has no such protection and isn't likely to because it's a compatibility change.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: wanted1.8.1.x+
Flags: blocking1.8.1.12?
Flags: blocking-firefox3?
Whiteboard: [sg:moderate]

Comment 4

10 years ago
we can autoresolve shortcut files in nsLocalFileWin (http://mxr.mozilla.org/seamonkey/source/xpcom/io/nsLocalFileWin.cpp#846).  

So, if you pass mozilla a file on the command line and this file is a shortcut and the nsLocalFileWin is autoresolving, my guess is that you will see something as described here -- a file: network load start that ends up loading whatever the file shortcut points to.

Maybe we can simply check if he incoming file on the command line is a shortcut, if it is, change it at that point to be he target of the file.
Flags: blocking1.8.1.12? → blocking1.8.1.13?
Rob, can you look at this and determine where it's happening?
Assignee: nobody → robert.bugzilla
Priority: -- → P2
This does not block the final release of Firefox 3.
Flags: blocking-firefox3? → blocking-firefox3-
Flags: blocking1.8.1.13? → blocking1.8.1.13+
Flags: blocking1.8.1.13+ → blocking1.8.1.14+
I took an initial look at this and I suspect that we are taking the .url file, going back to the OS, and then downloading the page. It appears that nsILocalFile only has a facility for resolving .lnk's and not .url's so we would have to add that capability somewhere. Chances are the reason it works when dropping a .url onto the urlbar is that we ask the OS for a url, the OS reads the url from the .url file, and the OS gives us the url.
Looks like nsClipboard.cpp uses nsIFileProtocolHandler ReadURLFile to handle this for DnD. I should have a patch by 4/11.

cc'ing bsmedberg
Created attachment 315139 [details] [diff] [review]
patch rev1

This basically uses the same method as used by nsClipboard.cpp
Attachment #315139 - Flags: review?(benjamin)
Whiteboard: [sg:moderate] → [sg:moderate][has patch][need review]
Comment on attachment 315139 [details] [diff] [review]
patch rev1

Benjamin, if you prefer I can if defined(XP_WIN) the new code.

Comment 11

10 years ago
Comment on attachment 315139 [details] [diff] [review]
patch rev1

This needs a unit test. And yes, I think we should #ifdef XP_WIN this, unless there's a known equivalent on mac/linux that we should be supporting.
Attachment #315139 - Flags: review?(benjamin) → review-
Whiteboard: [sg:moderate][has patch][need review] → [sg:moderate]
There is. Linux has .desktop files.
Created attachment 315661 [details] [diff] [review]
patch rev2 w/ test

Benjamin, I didn't ifdef the new code since it is implemented on Windows, Linux, and OS2. In the future it could be implemented on Mac OS X for .webloc files on Mac OS X.

I'm unsure how to best test per platform and just did a best effort at this time. Suggestions?

Also, I will put the data files in the subdirectory of unit/data when / if I land this.
Attachment #315139 - Attachment is obsolete: true
Attachment #315661 - Flags: review?(benjamin)
Created attachment 315677 [details] [diff] [review]
patch rev 3 w/ test

I went ahead and hacked the makefile so this test is preprocessed.
Attachment #315661 - Attachment is obsolete: true
Attachment #315661 - Flags: review?(benjamin)
Attachment #315677 - Flags: review?(benjamin)
Whiteboard: [sg:moderate] → [sg:moderate][has patch][need review]
(Reporter)

Comment 15

10 years ago
Not familiar with your code but this filetype is used on all versions of Windows so if the constant WIN_XP only gets defined under XP then it's still gonna be a problem for 9X and 2K. If WIN_XP gets defined under Windows in general, sorry for the spam.
It is just an unfortunate coincidence that there is an Windows XP OS and we use XP_WIN (XP = Cross Platform) in our code... hence why there is an XP_UNIX and XP_MACOSX even though there isn't a Mac OS X XP or UNIX XP.
Comment on attachment 315677 [details] [diff] [review]
patch rev 3 w/ test

>Index: toolkit/components/commandlines/test/unit/test_bug410156.desktop
>===================================================================
>RCS file: toolkit/components/commandlines/test/unit/test_bug410156.desktop
>diff -N toolkit/components/commandlines/test/unit/test_bug410156.desktop
>--- /dev/null	1 Jan 1970 00:00:00 -0000
>+++ toolkit/components/commandlines/test/unit/test_bug410156.desktop	15 Apr 2008 00:03:03 -0000
>@@ -0,0 +1,7 @@
>+[Desktop Entry]
>+Version=1.0
>+Encoding=UTF-8
>+Name=test_bug410156
>+Type=Link
>+URL=http://www.bug410156.com//
I removed the extra trailing / in my tree

Updated

10 years ago
Attachment #315677 - Flags: review?(benjamin) → review+
Comment on attachment 315677 [details] [diff] [review]
patch rev 3 w/ test

Drivers, this uses essentially the same code as the clipboard code for resolving urls within files (e.g. .url on Windows and .desktop on Linux) so it should be fairly safe. It also includes tests for both of these.
Attachment #315677 - Flags: approval1.9?
Whiteboard: [sg:moderate][has patch][need review] → [sg:moderate][has patch]
Flags: blocking-firefox3- → blocking-firefox3+
Comment on attachment 315677 [details] [diff] [review]
patch rev 3 w/ test

a1.9=beltzner
Attachment #315677 - Flags: approval1.9? → approval1.9+
Checked in to trunk

Checking in mozilla/toolkit/components/commandlines/src/nsCommandLine.cpp;
/cvsroot/mozilla/toolkit/components/commandlines/src/nsCommandLine.cpp,v  <--  nsCommandLine.cpp
new revision: 1.18; previous revision: 1.17
done
Checking in mozilla/toolkit/components/commandlines/test/Makefile.in;
/cvsroot/mozilla/toolkit/components/commandlines/test/Makefile.in,v  <--  Makefile.in
new revision: 1.2; previous revision: 1.1
done
RCS file: /cvsroot/mozilla/toolkit/components/commandlines/test/unit/test_bug410156.js.in,v
done
Checking in mozilla/toolkit/components/commandlines/test/unit/test_bug410156.js.in;
/cvsroot/mozilla/toolkit/components/commandlines/test/unit/test_bug410156.js.in,v  <--  test_bug410156.js.in
initial revision: 1.1
done
RCS file: /cvsroot/mozilla/toolkit/components/commandlines/test/unit/data/test_bug410156.desktop,v
done
Checking in mozilla/toolkit/components/commandlines/test/unit/data/test_bug410156.desktop;
/cvsroot/mozilla/toolkit/components/commandlines/test/unit/data/test_bug410156.desktop,v  <--  test_bug410156.desktop
initial revision: 1.1
done
RCS file: /cvsroot/mozilla/toolkit/components/commandlines/test/unit/data/test_bug410156.url,v
done
Checking in mozilla/toolkit/components/commandlines/test/unit/data/test_bug410156.url;
/cvsroot/mozilla/toolkit/components/commandlines/test/unit/data/test_bug410156.url,v  <--  test_bug410156.url
initial revision: 1.1
done
Status: NEW → RESOLVED
Last Resolved: 10 years ago
Resolution: --- → FIXED
Whiteboard: [sg:moderate][has patch] → [sg:moderate]
Target Milestone: --- → Firefox 3
Version: unspecified → 2.0 Branch
Comment on attachment 315677 [details] [diff] [review]
patch rev 3 w/ test

1.8.1.15 Drivers, this uses essentially the same code as the clipboard code for
resolving urls within files (e.g. .url on Windows and .desktop on Linux) so it
should be fairly safe. It also includes tests on trunk for both of these.
Attachment #315677 - Flags: approval1.8.1.15?
This bug seems to have burnt the Thunderbird: 'MacOSX Darwin 8.8.4 bm-xserve07 Depend Universal Nightly' tinderbox...
(In reply to comment #22)
> This bug seems to have burnt the Thunderbird: 'MacOSX Darwin 8.8.4 bm-xserve07
> Depend Universal Nightly' tinderbox...
Looking
I backed it out and will figure out a better way to do these tests
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Created attachment 316318 [details] [diff] [review]
Different approach to test

Benjamin, preprocessing seems to be more trouble than it is worth here so I took a different approach. The test on Linux and Windows are the same... they've just been split out into subdirs.
Attachment #316318 - Flags: review?(benjamin)

Updated

10 years ago
Attachment #316318 - Flags: review?(benjamin) → review+

Updated

10 years ago
Whiteboard: [sg:moderate] → [sg:moderate][has patch][has reviews]
Checked into Trunk

I didn't back out the test data files so only checked in the following

Checking in mozilla/toolkit/components/commandlines/src/nsCommandLine.cpp;
/cvsroot/mozilla/toolkit/components/commandlines/src/nsCommandLine.cpp,v  <--  nsCommandLine.cpp
new revision: 1.20; previous revision: 1.19
done
Checking in mozilla/toolkit/components/commandlines/test/Makefile.in;
/cvsroot/mozilla/toolkit/components/commandlines/test/Makefile.in,v  <--  Makefile.in
new revision: 1.5; previous revision: 1.4
done
RCS file: /cvsroot/mozilla/toolkit/components/commandlines/test/unit/win/test_bug410156.js,v
done
Checking in mozilla/toolkit/components/commandlines/test/unit/win/test_bug410156.js;
/cvsroot/mozilla/toolkit/components/commandlines/test/unit/win/test_bug410156.js,v  <--  test_bug410156.js
initial revision: 1.1
done
RCS file: /cvsroot/mozilla/toolkit/components/commandlines/test/unit/unix/test_bug410156.js,v
done
Checking in mozilla/toolkit/components/commandlines/test/unit/unix/test_bug410156.js;
/cvsroot/mozilla/toolkit/components/commandlines/test/unit/unix/test_bug410156.js,v  <--  test_bug410156.js
initial revision: 1.1
done
Status: REOPENED → RESOLVED
Last Resolved: 10 years ago10 years ago
Resolution: --- → FIXED
Whiteboard: [sg:moderate][has patch][has reviews] → [sg:moderate]
Flags: in-testsuite+
Comment on attachment 315677 [details] [diff] [review]
patch rev 3 w/ test

approved for 1.8.1.15, a=dveditz for release-drivers
Attachment #315677 - Flags: approval1.8.1.15? → approval1.8.1.15+
Checked into MOZILLA_1_8_BRANCH

Checking in mozilla/toolkit/components/commandlines/src/nsCommandLine.cpp;
/cvsroot/mozilla/toolkit/components/commandlines/src/nsCommandLine.cpp,v  <--  nsCommandLine.cpp
new revision: 1.13.2.2; previous revision: 1.13.2.1
done
Keywords: fixed1.8.1.15
Blocks: 408540
Verified with Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.15pre) Gecko/2008061005 BonEcho/2.0.0.15pre.
Keywords: fixed1.8.1.15 → verified1.8.1.15
Version: 2.0 Branch → Trunk
Alias: CVE-2008-2810
Group: security

Comment 30

9 years ago
Comment on attachment 315677 [details] [diff] [review]
patch rev 3 w/ test

a=asac for 1.8.0
Attachment #315677 - Flags: approval1.8.0.next+

Comment 31

9 years ago
Created attachment 355435 [details] [diff] [review]
for 1.8.0

Updated

9 years ago
Flags: blocking1.8.0.next+

Comment 32

5 months ago
Comment on attachment 315677 [details] [diff] [review]
patch rev 3 w/ test

>Index: toolkit/components/commandlines/src/nsCommandLine.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/toolkit/components/commandlines/src/nsCommandLine.cpp,v
>retrieving revision 1.17
>diff -u -8 -r1.17 nsCommandLine.cpp
>--- toolkit/components/commandlines/src/nsCommandLine.cpp	31 Dec 2007 15:15:44 -0000	1.17
>+++ toolkit/components/commandlines/src/nsCommandLine.cpp	15 Apr 2008 00:03:03 -0000
>@@ -90,16 +90,17 @@
>   typedef nsresult (*EnumerateHandlersCallback)(nsICommandLineHandler* aHandler,
> 					nsICommandLine* aThis,
> 					void *aClosure);
>   typedef nsresult (*EnumerateValidatorsCallback)(nsICommandLineValidator* aValidator,
> 					nsICommandLine* aThis,
> 					void *aClosure);
> 
>   void appendArg(const char* arg);
>+  void resolveShortcutURL(nsILocalFile* aFile, nsACString& outURL);
>   nsresult EnumerateHandlers(EnumerateHandlersCallback aCallback, void *aClosure);
>   nsresult EnumerateValidators(EnumerateValidatorsCallback aCallback, void *aClosure);
> 
>   nsStringArray     mArgs;
>   PRUint32          mState;
>   nsCOMPtr<nsIFile> mWorkingDir;
>   nsCOMPtr<nsIDOMWindow> mWindowContext;
>   PRBool            mPreventDefault;
>@@ -437,26 +438,36 @@
>   nsresult rv;
> 
>   // First, we try to init the argument as an absolute file path. If this doesn't
>   // work, it is an absolute or relative URI.
> 
>   nsCOMPtr<nsIIOService> io = do_GetIOService();
>   NS_ENSURE_TRUE(io, NS_ERROR_OUT_OF_MEMORY);
> 
>+  nsCOMPtr<nsIURI> workingDirURI;
>+  if (mWorkingDir) {
>+    io->NewFileURI(mWorkingDir, getter_AddRefs(workingDirURI));
>+  }
>+
>   nsCOMPtr<nsILocalFile> lf (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
>   rv = lf->InitWithPath(aArgument);
>   if (NS_SUCCEEDED(rv)) {
>     lf->Normalize();
>-    return io->NewFileURI(lf, aResult);
>-  }
>+    nsCAutoString url;
>+	// Try to resolve the url for .url files.
>+	resolveShortcutURL(lf, url);
>+    if (!url.IsEmpty()) {
>+      return io->NewURI(url,
>+                        nsnull,
>+                        workingDirURI,
>+                        aResult);
>+    }
> 
>-  nsCOMPtr<nsIURI> workingDirURI;
>-  if (mWorkingDir) {
>-    io->NewFileURI(mWorkingDir, getter_AddRefs(workingDirURI));
>+    return io->NewFileURI(lf, aResult);
>   }
> 
>   return io->NewURI(NS_ConvertUTF16toUTF8(aArgument),
>                     nsnull,
>                     workingDirURI,
>                     aResult);
> }
> 
>@@ -472,16 +483,32 @@
>   CopyUTF8toUTF16(nsDependentCString(arg), warg);
> #else
>   NS_CopyNativeToUnicode(nsDependentCString(arg), warg);
> #endif
> 
>   mArgs.AppendString(warg);
> }
> 
>+void
>+nsCommandLine::resolveShortcutURL(nsILocalFile* aFile, nsACString& outURL)
>+{
>+  nsCOMPtr<nsIFileProtocolHandler> fph;
>+  nsresult rv = NS_GetFileProtocolHandler(getter_AddRefs(fph));
>+  if (NS_FAILED(rv))
>+    return;
>+
>+  nsCOMPtr<nsIURI> uri;
>+  rv = fph->ReadURLFile(aFile, getter_AddRefs(uri));
>+  if (NS_FAILED(rv))
>+    return;
>+
>+  uri->GetSpec(outURL);
>+}
>+
> NS_IMETHODIMP
> nsCommandLine::Init(PRInt32 argc, char** argv, nsIFile* aWorkingDir,
>                     PRUint32 aState)
> {
>   NS_ENSURE_ARG_MIN(aState, 0);
>   NS_ENSURE_ARG_MAX(aState, 2);
> 
>   PRInt32 i;
>Index: toolkit/components/commandlines/test/Makefile.in
>===================================================================
>RCS file: /cvsroot/mozilla/toolkit/components/commandlines/test/Makefile.in,v
>retrieving revision 1.1
>diff -u -8 -r1.1 Makefile.in
>--- toolkit/components/commandlines/test/Makefile.in	7 Mar 2007 20:29:01 -0000	1.1
>+++ toolkit/components/commandlines/test/Makefile.in	15 Apr 2008 00:03:03 -0000
>@@ -40,14 +40,19 @@
> DEPTH		= ../../../..
> topsrcdir	= @top_srcdir@
> srcdir		= @srcdir@
> VPATH		= @srcdir@
> 
> include $(DEPTH)/config/autoconf.mk
> 
> MODULE		= test_harness_commandlines
>+TESTROOT	= $(shell cd $(DEPTH) && pwd)/_tests/xpcshell-simple/$(MODULE)
> 
> XPCSHELL_TESTS = \
>                  unit \
>                  $(NULL)
> 
> include $(topsrcdir)/config/rules.mk
>+
>+# Hack to allow preprocessing of test_bug410156.js
>+libs:: unit/test_bug410156.js.in
>+	$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $^ > $(TESTROOT)/unit/test_bug410156.js
>Index: toolkit/components/commandlines/test/unit/test_bug410156.js.in
>===================================================================
>RCS file: toolkit/components/commandlines/test/unit/test_bug410156.js.in
>diff -N toolkit/components/commandlines/test/unit/test_bug410156.js.in
>--- /dev/null	1 Jan 1970 00:00:00 -0000
>+++ toolkit/components/commandlines/test/unit/test_bug410156.js.in	15 Apr 2008 00:03:03 -0000
>@@ -0,0 +1,55 @@
>+/* ***** BEGIN LICENSE BLOCK *****
>+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
>+ *
>+ * The contents of this file are subject to the Mozilla Public License Version
>+ * 1.1 (the "License"); you may not use this file except in compliance with
>+ * the License. You may obtain a copy of the License at
>+ * http://www.mozilla.org/MPL/
>+ *
>+ * Software distributed under the License is distributed on an "AS IS" basis,
>+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
>+ * for the specific language governing rights and limitations under the
>+ * License.
>+ *
>+ * The Original Code is Command Line tests.
>+ *
>+ * The Initial Developer of the Original Code is
>+ * Robert Strong <robert_bugzila@gmail.com>.
>+ * Portions created by the Initial Developer are Copyright (C) 2007
>+ * the Initial Developer. All Rights Reserved.
>+ *
>+ * Contributor(s):
>+ *
>+ * Alternatively, the contents of this file may be used under the terms of
>+ * either the GNU General Public License Version 2 or later (the "GPL"), or
>+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
>+ * in which case the provisions of the GPL or the LGPL are applicable instead
>+ * of those above. If you wish to allow use of your version of this file only
>+ * under the terms of either the GPL or the LGPL, and not to allow others to
>+ * use your version of this file under the terms of the MPL, indicate your
>+ * decision by deleting the provisions above and replace them with the notice
>+ * and other provisions required by the GPL or the LGPL. If you do not delete
>+ * the provisions above, a recipient may use your version of this file under
>+ * the terms of any one of the MPL, the GPL or the LGPL.
>+ *
>+ * ***** END LICENSE BLOCK ***** */
>+
>+function run_test() {
>+  const Cc = Components.classes;
>+  var clClass = Cc["@mozilla.org/toolkit/command-line;1"];
>+  var commandLine = clClass.createInstance();
>+
>+#ifdef XP_WIN
>+  var urlFile = do_get_file("toolkit/components/commandlines/test/unit/data/test_bug410156.url");
>+  var uri = commandLine.resolveURI(urlFile.path);
>+  do_check_eq(uri.spec, "http://www.bug410156.com/");
>+#endif
>+
>+#ifdef XP_UNIX
>+#ifndef XP_MACOSX
>+  var urlFile = do_get_file("toolkit/components/commandlines/test/unit/data/test_bug410156.desktop");
>+  var uri = commandLine.resolveURI(urlFile.path);
>+  do_check_eq(uri.spec, "http://www.bug410156.com/");
>+#endif
>+#endif
>+}
>Index: toolkit/components/commandlines/test/unit/test_bug410156.desktop
>===================================================================
>RCS file: toolkit/components/commandlines/test/unit/test_bug410156.desktop
>diff -N toolkit/components/commandlines/test/unit/test_bug410156.desktop
>--- /dev/null	1 Jan 1970 00:00:00 -0000
>+++ toolkit/components/commandlines/test/unit/test_bug410156.desktop	15 Apr 2008 00:03:03 -0000
>@@ -0,0 +1,7 @@
>+[Desktop Entry]
>+Version=1.0
>+Encoding=UTF-8
>+Name=test_bug410156
>+Type=Link
>+URL=http://www.bug410156.com//
>+Icon=gnome-fs-bookmark
>Index: toolkit/components/commandlines/test/unit/test_bug410156.url
>===================================================================
>RCS file: toolkit/components/commandlines/test/unit/test_bug410156.url
>diff -N toolkit/components/commandlines/test/unit/test_bug410156.url
>--- /dev/null	1 Jan 1970 00:00:00 -0000
>+++ toolkit/components/commandlines/test/unit/test_bug410156.url	15 Apr 2008 00:03:03 -0000
>@@ -0,0 +1,9 @@
>+[InternetShortcut]
>+URL=http://www.bug410156.com/
>+IDList=
>+HotKey=0
>+[{000214A0-0000-0000-C000-000000000046}]
>+Prop3=19,2
>+[InternetShortcut.A]
>+[InternetShortcut.W]
>+URL=http://www.bug410156.com/
You need to log in before you can comment on or make changes to this bug.