There is a lot of talk about how an application should handle URL protocol handlers. Jesper Johanson has expressed his thoughts, as has David LeBlanc, Billy Rios, Window Snyder and pdp. Billy Rios just detailed yet another potential attack vector for protocol abuse.
I don’t think it is the responsibility of the calling application to perform input validation for the called application. However, I do think it is the responsibility of the calling application to ensure that the arguments to the called application are passed along properly, which is a subtle but important distinction.
When an application registers a URL handler there are only so many ways that it can do this. For the FirefoxURL handler Firefox specified HKLM\FirefoxURL\shell\open\command as
“path\to\firefox.exe” “%1″
Skype registers itself under the callto: protocol as
“C:\Programmer\Skype\Phone\Skype.exe” “/callto:%1″
Windows Address Book registers itself under the ldap: protocol as
“C:\Programmer\Outlook Express\wab.exe” /ldap:%1
And those are pretty much the different variations we can find for registering URL protocol handlers that are to be called from the command line. Most register with quotes directly around the %1 placeholder, some have quotes around the argument and the placeholder and others don’t even surround the placeholder with quotes.
In all these cases you can avoid the potential for mishap by either escaping quotes or whitespace. It should be possible for Internet Explorer, Firefox, Opera and Safari to embed a tiny bit of string handling logic into these very defined cases.
Coincidentally, Jesper published his post about how Mozilla does not escape these quotes either in his blog post on July 20. I had just written up this very same flaw in a vulnerability report two days before, on July 18, together with a proof-of-concept exploit that jumps from Firefox to Thunderbird. Separately from all of this the Mozilla Corporation were farsighted enough to include their “-osint” fix from Firefox 2.0.0.5 in Thunderbird 2.0.0.5, which was released on July 19.
As such, I am that vulnerability report unedited in my next article ![]()

[...] Handling URL protocol handlers [...]
Skype also registers itself under the “skype:” protocol handler.
One of the things you can do with this is to shutdown user’s Skype from remote.
I’ve published a proof of concept on my blog: http://aviv.raffon.net/2007/07/10/CrossApplicationScriptingWhoseFaultIsIt.aspx
Ideally the protocol handler should receive the input 100% unaltered. The problem is that IE and Firefox do not encode that input properly for the transport channel, which in this case is the command line, and therefor the input data alters the operation of the transport channel.
This is no different than HTTP Response Splitting where a literal line break would alter the operation of the transport channel (HTTP) and where the receiving party would get 100% unaltered input if the line break was properly escaped for the transport channel (%0A%0D).
Quotes have a special meaning on the command line and can be used to separate arguments, which is why you have escape characters such as \ or ^.
something.exe “test^” -arg ^”value”
would hand off a single argument to something.exe, and that argument would be the literal string
test” -arg “value
Regards
Thor Larholm
“Ideally the protocol handler should receive the input 100% unaltered,” you say, and on this I agree with that same 100%. However, you are clinging to the notion that “Quotes have a special meaning on the command line and can be used to separate arguments”. This is incorrect. Quotes have a special meaning to batch files, and to C/C++ console-mode programs, and possibly a number of others. That is a side-effect of the language chosen, not of the ‘command line’. Go look at stdargv.c in the C RTL - it parses a monolithic command line into an array of strings to hand it to the C main() function. If you’re writing a Win32 application, its WinMain() function receives a single, monolithic command line - unprocessed, uninterpreted, for the program to parse as it sees fit - even to completely ignore common argument separation syntax.
It is therefore the choice of the protocol handler’s author whether to submit to the run-time library’s command line parser, or to treat the command line as a single string.
Look at the definition of WinMain. http://msdn2.microsoft.com/en-us/library/ms633559.aspx - a single LPSTR, null-terminated (yeah, play with that)
If you’re writing a C/C++ program and want different command line parsing semantics, write your own _setargv routine, as described in http://msdn2.microsoft.com/en-us/library/ms857738.aspx
If you read my blog, you wouldn’t have attributed the parsing of arguments to some process that you theorise to exist between Internet Explorer’s call of ShellExecute and the loading of the executable’s code.
Alun, I don’t attribute the parsing to some theorized process, but I do believe that IE should implement some form of minimally invasive data encoding before handing off the string to the protocol handler. (For the other readers here, go read Aluns nice posts.)
I’m not suggesting that you take the route of Safari and indiscriminately URL encode the entire input string, which brings down the data delivery from 100% to some 25% (take a look at it, it’s horrible).
I just really think that we will have to settle for some minor inconvenience by accommodating a few outdated protocol handlers through some minor data encoding changes. Even outlook gets this wrong.
Standards and recommendations change over time and it’s time for us to be more specific about what we sent to all of those random protocol handlers that are present on a system. We have long since disabled SMTP relaying even though it was part of the standard and we just have to face the fact that most protocol handlers are not parsing their input correctly, but instead parsing the input as if it were a console command line.
Regards
Thor Larholm
You should link to Alun Jones’ insightful posts as well:
http://msmvps.com/blogs/alunj/archive/2007/07/22/firefoxurl-url-vulnerability.aspx
http://msmvps.com/blogs/alunj/archive/2007/07/23/firefoxurl-part-ii.aspx
In your reply to Alun’s comment, it sounds as though you’re arguing for breaking compatibility with existing (”outdated”) protocol handlers by changing what urlmon.dll passes to them, even though all of them not written by Mozilla may be correct the way they are. This won’t help security — if handlers are not validating their input, the URI provider will have innumerable ways to exploit them, whether urlmon.dll encodes spaces or not.
Aaron, I linked to them in my previous comment, but approved your comment as well to better point them out
Regards
Thor Larholm