From 2d170bd41fec93aae9a35dbf68aa6d758f10670d Mon Sep 17 00:00:00 2001 From: Unrud Date: Tue, 7 Mar 2017 17:44:07 +0100 Subject: [PATCH 1/2] Check for conflicting file names On Windows file systems the user "TESTUS~1" can access the data of the user "testuser". --- radicale/storage.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/radicale/storage.py b/radicale/storage.py index e38e3c4..e9d954a 100644 --- a/radicale/storage.py +++ b/radicale/storage.py @@ -172,7 +172,13 @@ def path_to_filesystem(root, *paths): for part in path.split("/"): if not is_safe_filesystem_path_component(part): raise UnsafePathError(part) + safe_path_parent = safe_path safe_path = os.path.join(safe_path, part) + # Check for conflicting files (e.g. case-insensitive file systems + # or short names on Windows file systems) + if os.path.lexists(safe_path): + if not part in os.listdir(safe_path_parent): + raise CollidingPathError(part) return safe_path @@ -182,6 +188,12 @@ class UnsafePathError(ValueError): super().__init__(message) +class CollidingPathError(ValueError): + def __init__(self, path): + message = "File name collision: %s" % path + super().__init__(message) + + class ComponentExistsError(ValueError): def __init__(self, path): message = "Component already exists: %s" % path From c6c32945a0d4de7bc81ae96ac6b9ac471735a5ea Mon Sep 17 00:00:00 2001 From: Unrud Date: Tue, 7 Mar 2017 17:50:20 +0100 Subject: [PATCH 2/2] Log unsafe paths when discovering collections --- radicale/storage.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/radicale/storage.py b/radicale/storage.py index e9d954a..af722c0 100644 --- a/radicale/storage.py +++ b/radicale/storage.py @@ -481,8 +481,9 @@ class Collection(BaseCollection): cls._makedirs_synced(folder) try: filesystem_path = path_to_filesystem(folder, sane_path) - except ValueError: + except ValueError as e: # Path is unsafe + cls.logger.info(e) return # Check if the path exists and if it leads to a collection or an item