Pylons Security Advisory
Topic: Path traversal bug in default error controller
Module: controllers/error.py
Announced: 2008-05-15
Credits: Webwise Security
Affects: All Pylons releases with Routes < 1.7.3
Corrected: Routes 1.7.3 or greater
Pylons 0.9.6.2I. BackgroundThe Pylons error.py controller is a default controller created in new Pylons projects. It handles serving media and the default error page for a Pylons
application. II. Problem DescriptionThe error.py controller uses paste.fileapp to serve the static resources to the browser. The default error.py controller uses os.path.join to combine the id from Routes with the media path. Routes prior to 1.8 double unquoted the PATH_INFO, resulting in FileApp returning files from the filesystem that
can be outside of the intended media path directory. III. ImpactAn attacker can craft URL's which utilize the double escaping to pass in a name to the error.py controller which contains a leading slash thus escaping the intended media path and serving files from any location on the filesystem
that the Pylons application has access to. IV. Workaround Any of the following will prevent the file traversal: 1) Upgrade Routes to Routes 1.7.3 (easy_install -U Routes)This is a fix only for the multiple escaping which made it possible to
exploit FileApp. 2) Remove the methods 'img' and 'style' from the ErrorController insidecontrollers/error.py. These methods are only needed to serve the default error media, customizing the error page to render your own template doesn't
require these 2 methods. 3) Patch the controllers/error.py controller to import urllib, and then urllib.quote_plus the id values before having them served by the fileapp. V. SolutionFor new Pylons projects, starting with Pylons 0.9.6.2, the project template
will include changes to ensure that the base media path is not escaped. For existing Pylons projects perform one of the following:1) Update the pylons/error.py to use the StaticURLParser, this requires the
following changes:
a) Replace the fileapp import at the top with:
from paste.urlparser import StaticURLParser
b) Replace the img, style and _serve_file methods with the
following ones:
def img(self, id):
"""Serve Pylons' stock images"""
return self._serve_file(os.path.join(media_path, 'img'), id)
def style(self, id):
"""Serve Pylons' stock stylesheets"""
return self._serve_file(os.path.join(media_path, 'style'),
id)
def _serve_file(self, root, path):
"""Call Paste's FileApp (a WSGI application) to serve the
file
at the specified path
"""
static = StaticURLParser(root)
request.environ['PATH_INFO'] = '/%s' % path
return static(request.environ, self.start_response)
2) Remove the 'img' and 'style' methods entirely. If the error.py
'document'
method is loading a custom error handler, the additional methods
to load
Pylons media for the default error page is unnecessary.3) Upgrade to Routes 1.7.3. This will prevent the double unquoting behavior, but is not as secure as option (1) as there is still no additional check that fileapp is being constrainted to the appropriate media directories.
smime.p7s
Description: S/MIME cryptographic signature
