changeset 17:27bd18f0a359

fix up security hole
author Jeff Hammel <jhammel@mozilla.com>
date Wed, 29 Feb 2012 16:01:38 -0800
parents 4f26df21dc12
children 76c939271534
files fileserver/web.py tests/doctest.txt
diffstat 2 files changed, 13 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/fileserver/web.py	Wed Feb 29 15:47:24 2012 -0800
+++ b/fileserver/web.py	Wed Feb 29 16:01:38 2012 -0800
@@ -49,6 +49,15 @@
     def normpath(path):
         return os.path.normcase(os.path.abspath(path))
 
+    def check_path(self, path):
+        """
+        if under the root directory, returns the full path
+        otherwise, returns None
+        """
+        path = self.normpath(path)
+        if path == self.directory or path.startswith(self.directory + os.path.sep):
+            return path
+
     def index(self, directory):
         """
         generate a directory listing for a given directory
@@ -69,9 +78,9 @@
         if not path_info:
             response = exc.HTTPMovedPermanently(add_slash=True)
             return response(environ, start_response)
-        full = self.normpath(os.path.join(self.directory, path_info.strip('/')))
+        full = self.check_path(os.path.join(self.directory, path_info.strip('/')))
 
-        if not full.startswith(self.directory):
+        if full is None:
             # Out of bounds
             return exc.HTTPNotFound()(environ, start_response)
         if not os.path.exists(full):
--- a/tests/doctest.txt	Wed Feb 29 15:47:24 2012 -0800
+++ b/tests/doctest.txt	Wed Feb 29 16:01:38 2012 -0800
@@ -80,6 +80,7 @@
 
 Ensure you can't get to non-allowed resources::
 
-    >>> response = testapp.get('/../exampleBADBADBAD')
+    >>> response = testapp.get('/../exampleBADBADBAD', status=404)
     >>> response.status # Not Found: we do not want to give away these resources
     404
+