flawopen.com/Обход пути/Python os.path.join()
Защищает ли Python os.path.join() от Path Traversal?
Нет. Представьте базовый каталог комнатой: .. ведет через родительские комнаты наружу; абсолютный путь — новый адрес, из-за которого os.path.join() отбрасывает исходную комнату. Разрешите итоговый путь и проверьте, что он остается в разрешенном каталоге, прежде чем открыть файл.
import os base_dir = "/srv/uploads" user_filename = "../../outside/demo.txt" path = os.path.join(base_dir, user_filename) # Relative traversal can leave the base. path = os.path.join(base_dir, "/outside/demo.txt") # An absolute segment discards base_dir.
import os
def resolve_under_base(base_dir, user_filename):
if not isinstance(user_filename, str) or not user_filename:
raise ValueError("Invalid filename")
base = os.path.realpath(base_dir)
candidate = os.path.realpath(
os.path.join(base, user_filename)
)
try:
inside = os.path.commonpath((base, candidate)) == base
except ValueError: # e.g. different Windows drives
inside = False
if not inside or candidate == base:
raise ValueError("Invalid filename")
return candidate
Два свойства объединения путей
Компонент .. может вывести относительный путь из нужного каталога. По документации Python абсолютный компонент заставляет os.path.join() отбросить предыдущие; правила дисков и корней Windows отличаются от POSIX. pathlib.Path(base) / user_input ведет себя так же. Объединение и нормализация не проверяют права.
Почему commonpath() безопаснее строковых префиксов
Перед сравнением разрешите доверенную базу и кандидат. os.path.commonpath() сравнивает компоненты, а не префиксы символов, и вызывает ValueError для несовместимых корней или дисков; отклоняйте такие случаи. realpath() разрешает ссылки на момент проверки, но не мешает изменить их до открытия. Если дерево доступно для изменения, используйте подходящие дескрипторы и no-follow.
- ✓Отклоняйте пустые значения и входные данные не типа string.
- ✓Разрешите базу и кандидат; требуйте
commonpath((base, candidate)) == base. ОтклоняйтеValueErrorи саму базу, если нужен файл. - ✓Отделяйте проверку границ от авторизации; разрешайте только нужные endpoint файлы и операции.
- ✓При возможности менять ссылки предотвращайте гонку проверки и использования подходящими API дескрипторов.
Частые вопросы
Да. Оператор / у Path отбрасывает предыдущие компоненты, если следующий путь абсолютный. Разрешите результат и проверьте разрешенную базу.
Нет. Он разрешает ссылки при проверке; другой процесс может изменить их до открытия. Ограничьте запись или используйте поддерживаемые операции относительно дескриптора с no-follow.