Условие сравнивает дочерний путь с родителями исходного пути, то есть проверка направлена неверно. Для /home/user/app/ и dir1/dir2 оно истинно и возбуждает PermissionDenied, хотя путь находится внутри.
Валидация вложенного пути в файловой системе
Условие сравнивает дочерний путь с родителями исходного пути, то есть проверка направлена неверно. Для /home/user/app/ и dir1/dir2 оно истинно и возбуждает PermissionDenied, хотя путь находится внутри.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Опишите, какую именно проверку осуществляет условный оператор и при каких значениях переменных условие будет истинным.
# model.path: pathlib.Path
# model.path = pathlib.Path("/home/user/app/")
# PERMITTED_SUBPATH = "dir1/dir2"
if model.path / PERMITTED_SUBPATH not in model.path.parents:
raise django.core.exceptions.PermissionDenied()
Ответ
Условие сравнивает дочерний путь с родителями исходного пути, то есть проверка направлена неверно. Для /home/user/app/ и dir1/dir2 оно истинно и возбуждает PermissionDenied, хотя путь находится внутри.
model.path.parents содержит /home/user, /home и /, но не /home/user/app/dir1/dir2. Для проверки вложенности сначала нормализуйте обе стороны:
base = model.path.resolve()
candidate = (base / PERMITTED_SUBPATH).resolve()
if not candidate.is_relative_to(base):
raise PermissionDenied()
Нужно импортировать PermissionDenied из django.core.exceptions. is_relative_to допускает равенство base; при необходимости запретите его отдельно. resolve учитывает symlinks, но не устраняет гонку их изменения между проверкой и открытием; для недоверенной файловой системы нужны безопасные операции относительно дескриптора каталога.