Convert filesystem paths safely to paths

This only becomes a problem if the OS/filesystem
allows / in filenames or . respectively
.. as filenames.
This commit is contained in:
Unrud 2015-12-24 14:25:34 +01:00
parent bcaf452e51
commit eed37792ae
2 changed files with 19 additions and 1 deletions

View File

@ -40,6 +40,18 @@ def sanitize_path(path):
return new_path + trailing_slash return new_path + trailing_slash
def is_safe_path_component(path):
"""Checks if path is a single component of a path and is safe to join"""
if not path:
return False
head, _ = posixpath.split(path)
if head:
return False
if path in (".", ".."):
return False
return True
def is_safe_filesystem_path_component(path): def is_safe_filesystem_path_component(path):
"""Checks if path is a single component of a local filesystem path """Checks if path is a single component of a local filesystem path
and is safe to join""" and is safe to join"""

View File

@ -29,7 +29,7 @@ import time
import sys import sys
from contextlib import contextmanager from contextlib import contextmanager
from .. import config, ical, pathutils from .. import config, ical, log, pathutils
FOLDER = os.path.expanduser(config.get("storage", "filesystem_folder")) FOLDER = os.path.expanduser(config.get("storage", "filesystem_folder"))
@ -100,6 +100,12 @@ class Collection(ical.Collection):
filesystem_path = pathutils.path_to_filesystem(path, FOLDER) filesystem_path = pathutils.path_to_filesystem(path, FOLDER)
_, directories, files = next(os.walk(filesystem_path)) _, directories, files = next(os.walk(filesystem_path))
for filename in directories + files: for filename in directories + files:
# make sure that the local filename can be translated
# into an internal path
if not pathutils.is_safe_path_component(filename):
log.LOGGER.debug("Skipping unsupported filename: %s",
filename)
continue
rel_filename = posixpath.join(path, filename) rel_filename = posixpath.join(path, filename)
if cls.is_node(rel_filename) or cls.is_leaf(rel_filename): if cls.is_node(rel_filename) or cls.is_leaf(rel_filename):
yield cls(rel_filename) yield cls(rel_filename)