Hey, Mozilla: Quotes Are Not Legal in a URL
When I was a child, I learned a saying that I still find important to keep in mind:
Those who are sitting in a glass house shall not throw stones
The good folks at Mozilla may want to look up what that really means. Two days ago, Mozilla published Firefox version 2.0.0.5 to fix a security vulnerability resulting from an interaction between Firefox and Internet Explorer (IE). Put briefly, if a user that has Firefox installed uses Internet Explorer to browse to a malicious site that malicious site can cause IE to spawn Firefox on the user's computer. Firefox, in turn, fails to validate the input it receives from IE, and will run arbitrary code of the bad guy's choosing on the user's computer. This is especially valuable to criminals on Windows Vista since IE runs in protected mode on Vista by default, providing a layer of protection from malicious web code. Firefox does not have any such protection and executes with the full privileges of the locally logged on user.
In conjunction with the fix, Mozilla's Chief Security Something-or-Other, Window Snyder, wrote a blog post where she states that "This patch for Firefox prevents Firefox from accepting bad data from Internet Explorer. It does not fix the critical vulnerability in Internet Explorer. Microsoft needs to patch Internet Explorer..." [emphasis in the original]. The IE team, meanwhile, has stated that they do not intend to fix what they see as Mozilla's problem.
Well Window, those who sit in a glass house should not be throwing stones. Let's take a look at the issue, shall we?
Window's claim that this is a critical vulnerability rests on RFC 3986, which defines the standard Uniform Resource Identifier (URI) syntax. Section 2 of that RFC states that a URI consists of a limited set of characters; basically numbers, letters, and a few non-alphanumerics. It goes on to state that other characters are encoded using percent encoding. Specifically: "the only time when octets within a URI are percent-encoded is during the process of producing the URI from its component parts" (RFC 3986, section 2.4). The people who argue that Microsoft is at fault in passing the URI on to Firefox apparently take that statement to mean that IE should be encode the URI before passing it on to the protocol handler. Personally, I fail to see how taking a link on a page and passing it on to the handler that deals with that link constitutes "producing the URI from its component parts" but I could be missing something. I think the statement about percent encoding applies to the bad guy that constructed the URI in the first place, and the application that ultimately executes it. Therein lies the rationale behind my claim that the flaw is in the protocol handler, i.e. Firefox in this case.
However, let's assume that we take Mozilla's claims at face value; that IE really is at fault here. Window goes on to claim that this is a serious issue also affecting other applications. In fact, she points to a different article that demonstrates how to execute arbitrary code in Trillian using this "IE flaw". Thor Larholm adds a list of other protocol handlers, which can be passed arbitrary command line arguments, although this is merely a list of some protocol handlers, not a list of vulnerable ones. Window finishes her post with the usual line: "Mozilla recommends using Firefox to browse the web to prevent attackers from taking advantage of this vulnerability in Internet Explorer."
That would be sage advice, if:
-
This were actually a vulnerability in IE, and not a failure of Firefox and Trillian to validate input, and
-
If Mozilla were any safer
Just for fun, I decided to conduct a little test of that second hypothesis. I used the very simple protocol handler I wrote for the previous blog post:
#include <stdio.h>
int main(int argc, char* argv[])
{
// The URL is in argv
printf("\nThere are %d arguments in the URL\n", argc);
for(int i=0;i<argc;i++)
{
printf("\nArgument %d:\t%s",i,argv[ i ]);
}
printf("\n");
char c;
c = getc(stdin);
}
This program lets us inspect what the browser that calls the protocol handler actually passes on to that protocol handler. In other words, it lets us see exactly what Firefox and Trillian see when they are invoked using their respective protocols from a browser. The URL that is passed by the browser to the handler is passed as a command line argument (this is the argv parameter, in case your C is a bit rusty). The program simply enumerates all the command line arguments and prints them. To do that it needs to be registered, which we do with a reg script, like this:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\TestURL]
@=URL:Test Protocol
"URL Protocol"=""
[HKEY_CLASSES_ROOT\TestURL\DefaultIcon]
@="cmd.exe"
[HKEY_CLASSES_ROOT\TestURL\shell]
[HKEY_CLASSES_ROOT\TestURL\shell\open]
[HKEY_CLASSES_ROOT\TestURL\shell\open\command] @="\"c:\\test.exe\" \"%1\""
We now have a program that handles the TestURL protocol, invoked by calling testurl://<location>. To test it, I downloaded Thor Larholm's sample exploit, and changed it to call the TestURL protocol instead. The original script said:
<iframe src='firefoxurl://larholm.com"...
And my modified version said:
<iframe src='testurl://larholm.com"...
To test it, I opened the sample exploit using IE on a fully patched Windows Vista computer. IE, on Vista, will prompt you whether you want to open the external program or not, as shown in this picture:
If you click allow, you get this output:

It all seems to work. I get four command line arguments (three of which are part of the URL), which is what we would expect if the calling application, IE, or more specifically, urlmon.dll, does not escape the quotes in the URL. This is the crux of Mozilla's and Thor's claims. They want IE to escape the quotes so the URL is passed as a single command line argument.
Now, what do you suppose happens when you run the sample exploit using Firefox? First, you will get a big scary warning:

Cool. Firefox shows the user the entire URL. I wonder if that helps people in general make security decisions? Note also that the quotes are not escaped. Clearly, that must come later. To see, click "Launch Application" and you will get this output:

Can you spot the glass house too? To paraphrase Window: "This patch for Firefox ... does not fix the critical vulnerability in Firefox."
That's correct. Following Mozilla's, and Thor Larholm's logic, Firefox is subject to the exact same flaw that they blame on IE! Firefox also does not escape quotes in URLs before it passes them on to protocol handlers. I won't speculate here on why they failed to fix that "flaw" in the new version of Firefox that was just released.
Now, ordinarily I would not release details of an exploit without notifying the vendor first and giving them a reasonable chance to fix it. However, as I have claimed all along that the flaw is that the protocol handler fails to validate its inputs, I do not consider this particular issue to be a flaw in Firefox at all. Therefore, I do not believe I am engaging in irresponsible disclosure by letting people know that Firefox also does not protect users of Trillian from flaws in Trillian. I would never do such a thing, and I am sure Window will agree with me.
Update July 23, 2007
Replaced text output with screenshots because the exploit script did not render properly as some of it was blocked by the security filters on the blog. Also added a picture of the IE warning upon launching an external protocol handler outside of protected mode.