(For my german Heise visitors: Bleibt doch mal ein bischen und abonniert mein Feed, ich werde zusätzliche Schwachstellen veröffentlichen).

The patch from Bugzilla report 367428 that was introduced in Firefox 2.0.0.4 accidentally opens up the resource protocol to a separate input validation flaw. But first, a recap.

There were a number of interesting comments on my previous post, Firefox 0day local file reading. Checking the current Windows patch status was suggested by Sergey Vzloman and H D Moore highlighted what has now become general knowledge – that the directory traversal vulnerability in Firefox 2.0.0.3 is still present in the updated Firefox 2.0.0.4 under Linux/Unix and OS X.

The patch only closes the directory traversal aspect on Windows. You can still read local files in Firefox 2.0.0.4 on Windows, but it is now limited to the files within your Firefox installation directory such as update.xml and install.log that reveal your current Firefox patch status. It is still possible to determine the local installation path and query for the installation status of arbitrary plugin DLL’s, as I demonstrated with the PoC in my previous post. Non-Windows operating systems are still vulnerable to the full directory traversal vulnerability, allowing you to read any local files that your user account can reach.

Before the 2.0.0.4 patch the input to nsResProtocolHandler::ResolveURI was already checked to prevent any : characters from sneaking in, which can allow absolute URI references such as “res:C:boot.ini” or “res:http://www.google.com/”. This check is still in place in lines 334 to 336.

    // Don't misinterpret the filepath as an absolute URI.
    if (filepath.FindChar(':') != -1)
        return NS_ERROR_MALFORMED_URI;

Since the previous directory traversal vulnerability depended on URL-escaped characters such as %5C to work the patch added the currently present lines 338 to 340.

    NS_UnescapeURL(filepath);
    if (filepath.FindChar('\\') != -1)
        return NS_ERROR_MALFORMED_URI;

Since the filepath is now unescaped after the check for a : character has occurred, it is possible to inject : characters with the URL-escaped version %3A.

A non-malicious example request that can be used for verification is the following link include, which passes on unfiltered : characters to the host file system.

<link rel="stylesheet" href="resource://gre/browserconfig%3A.properties" />

It is also possible to pass on @ characters to the host file system, which at least on the Windows platform can be used to implement Basic Authentication style URI’s.

There are some odd URI resolver logic in nsIStandard::Resolve that I will still have to look into. Under some circumstances on Windows, I can get / characters translated into \ characters and have triple dots translated into double dots, which will once again allow the full directory traversal vulnerability. However, the output is flaky at best and I will have to do some tedious single stepping through the URI resolver logic code to determine at what point the input is unescaped twice :)