diff --git a/radicale/__init__.py b/radicale/__init__.py index 12932e8..8ded6d1 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -32,7 +32,6 @@ import os import sys import pprint import base64 -import posixpath import socket import ssl import wsgiref.simple_server @@ -48,7 +47,7 @@ except ImportError: from urlparse import urlparse # pylint: enable=F0401,E0611 -from . import auth, config, ical, log, rights, storage, xmlutils +from . import auth, config, ical, log, pathutils, rights, storage, xmlutils VERSION = "1.0.1" @@ -179,15 +178,7 @@ class Application(object): def sanitize_uri(uri): """Unquote and make absolute to prevent access to other data.""" uri = unquote(uri) - trailing_slash = "/" if uri.endswith("/") else "" - uri = posixpath.normpath(uri) - new_uri = "/" - for part in uri.split("/"): - if not part or part in (".", ".."): - continue - new_uri = posixpath.join(new_uri, part) - trailing_slash = "" if new_uri.endswith("/") else trailing_slash - return new_uri + trailing_slash + return pathutils.sanitize_path(uri) def collect_allowed_items(self, items, user): """Get items from request that user is allowed to access.""" diff --git a/radicale/pathutils.py b/radicale/pathutils.py new file mode 100644 index 0000000..5a0e0c8 --- /dev/null +++ b/radicale/pathutils.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# +# This file is part of Radicale Server - Calendar Server +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Radicale. If not, see . + +""" +Helper functions for working with paths + +""" + +import posixpath + + +def sanitize_path(path): + """Make absolute (with leading slash) to prevent access to other data. + Preserves an potential trailing slash.""" + trailing_slash = "/" if path.endswith("/") else "" + path = posixpath.normpath(path) + new_path = "/" + for part in path.split("/"): + if not part or part in (".", ".."): + continue + new_path = posixpath.join(new_path, part) + trailing_slash = "" if new_path.endswith("/") else trailing_slash + return new_path + trailing_slash \ No newline at end of file