# HG changeset patch # User Jeff Hammel # Date 1330560098 28800 # Node ID 27bd18f0a3595972f9599bb248d3345e1c895700 # Parent 4f26df21dc1214df83b90713a74bf7afa955d175 fix up security hole diff -r 4f26df21dc12 -r 27bd18f0a359 fileserver/web.py --- 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): diff -r 4f26df21dc12 -r 27bd18f0a359 tests/doctest.txt --- 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 +