CreateURLMoniker Considered Harmful


While working on IE7 application compatibility, we’ve seen many cases of interesting and strange invalid file URIs. I believe a substantial amount of responsibility for the confusion over file URIs lies with the deprecated urlmon.dll function CreateURLMoniker. This function is used by Windows application developers mainly to convert a string URI into an object that can be used to obtain the data represented by the URI. CreateURLMoniker does a couple of horrible things to file URIs that if misused can lead to security bugs. For those application developers who have used this function in the past allow me to describe what’s wrong with CreateURLMoniker and what to use instead.

Solution

If you’re not a Windows application developer or you’re not interested in the details and don’t plan on reading any further here is the solution up front: Use CreateURLMonikerEx with the flag URL_MK_UNIFORM instead of CreateURLMoniker to avoid problems with file URIs. The problems with CreateURLMoniker were discovered sometime ago and this flag was introduced to allow people to switch to a valid URI parser that will do the correct thing with file URIs. We couldn’t switch to using the valid URI parser without breaking a huge number of applications that depend on this functionality.

Additionally, if what you’d like to do is convert between a file URI and Windows file path, the shlwapi.dll functions PathCreateFromUrl and UrlCreateFromPath will do this correctly.

Problems

The first problem concerns the IMoniker output of CreateURLMoniker. A call to IMoniker::GetDisplayName will produce a string containing an invalid file URI. It will be in the form that Zeke named Legacy File URI and described on his blog. This form cannot be parsed with a general URI parser and as such may not be compatible with some APIs.

The second problem concerns the input to CreateURLMoniker. CreateURLMoniker will decode any percent-encoded octet (except ‘%00’) in a file URI or Windows file path provided as input. This means that the URI you get out of CreateURLMoniker in IMoniker form may not necessarily be equivalent to the URI provided. As noted in the URI standard you can’t decode just any percent-encoded octet and expect to get an equivalent URI back. If that were the case there wouldn’t be any point to percent-encoding in URIs.

Since CreateURLMoniker will decode ‘%25’ to its corresponding ‘%’ the process is not idempotent. This means that applying CreateURLMoniker to a URI again and again may produce a different URI each time.

Examples

For example given the following Windows file path, the corresponding correct file URI, and the output from CreateURLMoniker follow:

       Original Path:
C:Documents and SettingsdavrisProject100%28years.xsl
    
Correct URI:
file:///C:/Documents%20and%20Settings/davris/Project100%2528years.xsl

       CreateURLMoniker Result:
file://C:Documents and SettingsdavrisProject100(years.xsl

Note that the result from CreateURLMoniker identifies a file named “Project100(years.xsl” rather than the intended file name “Project100%28years.xsl”.

As noted above CreateURLMoniker is not idempotent. For example, starting with the following Windows file path and passing each resulting string back through CreateURLMoniker gives the following sequence of results:

Windows file path:      C:foo%25252544.txt
CreateURLMoniker call 1:     file://C:foo%252544.txt
CreateURLMoniker call 2:     file://C:foo%2544.txt
CreateURLMoniker call 3:     file://C:foo%44.txt
CreateURLMoniker call 4:     file://C:fooD.txt

This can lead to security problems in which one portion of a system believes its working with one URI while another portion of the system that has run its URI through CreateURLMoniker a different number of times believes its working on a different URI.

Changes in IE7

In IE7 we still cannot change CreateURLMoniker to use proper file URI parsing for application compatibility reasons. However, we decided to make a change to help with the idempotence problem: CreateURLMoniker will no longer decode ‘%25’ to ‘%’. This means in IE7, while CreateURLMoniker will still give back an IMoniker that may not be equivalent to the input URI the CreateURLMoniker process won’t be able to produce a new URI after every CreateURLMoniker call as seen in the example above. This is a change in behavior from IE6 and it is noted in the application compatibility logging.

However, this doesn’t address all problems of CreateURLMoniker. To reiterate, if you need an URL Moniker please use the function CreateURLMonikerEx with the flag URL_MK_UNIFORM.

We have updated the MSDN documentation to mark CreateURLMoniker as deprecated and to include the solution described here.

Dave Risney
Software Design Engineer

Comments (15)

  1. Dave2 says:

    Dave, I’ve heard that insanity is defined as doing the same thing over and over, expecting a different result. If that is true, then CreateURLMoniker seems to be a great implementation of insanity.

    Your second example reminds me of my cat. It keeps calling until I let it in and it gets "FooD". I guess that means my cat is insane. But not hungry.

    Seriously though, I assume the reason you don’t just yank CreateURLMoniker is because it is well-behaved for many "normal" file names?

  2. EricLaw [MSFT] says:

    Unfortunately, we wouldn’t be able to "yank" CreateURLMoniker without breaking many applications already out in the field that rely upon it.  Changing its behavior is similarly problematic, because some applications may rely on its (mis-)behavior.

  3. i don’t have any problems with this RC1 version

  4. hAl says:

    It would be preferrable if you would inform us if this feature will be dropped in futere versions. Problaby IE8 is still a year away so that would give every application builder plenty of time.

  5. Need a IE7 uninstaller for windows sp2 and vista RC1.

    thanks.

  6. Steve says:

    ********** ********** **********

    ********** ********** **********

    ********** ********** **********

    ********** ********** **********

    ONCE AGAIN, TELL THE FOLKS IN THE MS OUTLOOK GROUP, WHEN THEY ISSUE AUTOMATIC UPDATES FOR BUGS, SECURITY HOLES OR WHATEVER, TO NOT _NOT_ *NOT* EVER, EVER, EVER CHANGE THE DEFAULT EMAIL CLIENT IN WINDOWS, TO OUTLOOK.

    NOT ONLY IS THIS EXTREMELY ANOYING FOR EVERYONE THAT DOESN’T USE OUTLOOK (OR WANT TO), BUT IT MIGHT BE CONSIDERED A MONOPOLISTIC TYPE OF BEHAVIOUR!

    THIS IS THE 4TH TIME THAT I HAVE COUNTED, IN CONSECUTIVE AUTOMATIC UPDATES THAT THIS TYPE OF SHENANIGANS HAS GONE ON.

    PLEASE, SOMEONE BLAST THE HORN AT THIS DEPT. AND GET THEM TO SHAPE UP!

    ********** ********** **********

    ********** ********** **********

    ********** ********** **********

    ********** ********** **********

    (YES, THE COMMENT IS ANOYINGLY PADDED, TO GET SOME ATTENTION THAT HAS CLEARLY BEEN MISSING. AND YEAH, I KNOW I’M YELLING… AT LEAST I EDITED OUT THE CURSE WORDS THAT WERE IN HERE WHEN I WROTE THIS)

    ********** ********** **********

    ********** ********** **********

    ********** ********** **********

    ********** ********** **********

  7. Adam says:

    @Steve,

    I have used Thunderbird for quite a while(at home), and I have never had Windows switch the default email client back to Outlook after an update.

    Of course, I am referring to updates that come through Windows/Microsoft/Office update.

    What updates are you referring to? I assume you are using XP? Perhaps I am the exception?

    Also, I would recommend that you contact the Outlook group directly or through their blog (if they have one). I don’t believe that the IE team deals directly with outlook, or windows updates.

  8. Aaron says:

    I apologize in advance, as this does not relate to the topic at hand.  However, I am not sure where to raise this issue and so I will do it here.  Let me know if there is a better place for me to bring this up.

    It seems that when I installed IE7, my system lost (for lack of a better word) the list of the programs associated with the Microsoft Office file extensions (e.g., my computer no longer recognized .doc as a Word file).  While I have been able to re-associate these programs with their respective file extensions, IE7 still does not recognize a few of them (the most prevalent is the .doc extension).  Instead of having the ability to open a Word document directly in my browser, I am forced to save the file and open it later in Word.  Could someone please help me?  

  9. Steve says:

    @Adam,

    yes, the outlook group would be much better, but getting anyone at MS to communicate, without fees involved is pretty scarce.  As it stands, there are some key developers on the IE team, that realize the importance of good software, etc.

    I use Thunderbird also.. but in the last 4 AU’s, each one, that had patches for Outlook, included a reset of the default email client flag.

    I’m forced to use MS Office for some documents etc. but thankfully I’ve never had to use Outlook… except of course, when the automatic updates come along, and try to convert me.

    As posted on here before, if a direct link to a feedback form for the Outlook team could be provided, I’d be glad to send my comments that way.

  10. fr says:

    a couple of outlook related blogs which might be worth trying…

    http://blogs.msdn.com/willkennedy/

    http://blogs.msdn.com/michael_affronti/

  11. Mike says:

    > a couple of outlook related blogs which might be worth trying…

    > http://blogs.msdn.com/willkennedy/

    Great to have an Outlook blog, but slightly worrying when it hasn’t been updated since December 2005!

  12. One of the examples of "healthy" file URLs on the FreeAssociations blog you link to is, as far as I know, wrong. Comments are closed there, so I’ll mention it here 🙂 The blog says:

    DOSPATH:         \servershareMy Documents 100%20foo.txt

    HEALTHY:         file://server/share/My%20Documents%20100%2520/foo.txt

    LEGACY:          file://\servershareMy Documents 100%20foo.txt

    The healthy URL in this case should surely be:

    file://///server/share/My%20Documents%20100%2520/foo.txt

    i.e. five leading slashes, not two. Why?

    – file:// is the protocol start, like http://.

    – Then you have a host. However, as file: is a local machine protocol rather than a network protocol, there is never a host. The host is followed by a slash, so you have file:///.

    – Next up is the path, relative to the local machine. The path is \servershareetc. Convert that to URL-style slashes, and you get:

    file://///server/share/…

    This form of file URL works everywhere (specifically, in Firefox); other forms don’t.

  13. DavRis [MSFT] says:

    @Gervase Markham,

    The file URIs listed on Zeke’s blog post are correct.

    Wrt your second point there can be hosts in a file URI.  Although the RFC doesn’t specify a network protocol, that doesn’t mean that the file scheme is limited to the local machine.

    From RFC 1738 <http://tools.ietf.org/html/?rfc=1738&draft=&submit=Submit#section-3.10&gt;

      A file URL takes the form:

          file://<host>/<path>

      where <host> is the fully qualified domain name of the system on

      which the <path> is accessible, and <path> is a hierarchical

      directory path of the form <directory>/<directory>/…/<name>.

      As a special case, <host> can be the string "localhost" or the empty

      string; this is interpreted as `the machine from which the URL is

      being interpreted’.

      The file URL scheme is unusual in that it does not specify an

      Internet protocol or access method for such files; as such, its

      utility in network protocols between hosts is limited.

  14. IEBlog says:

    Invalid file URIs are among the most common illegal URIs that we were forced to accommodate in IE7. As

  15. IEBlog says:

    Investigating URI parsing related issues in various products, I’ve run across many instances of code

Skip to main content