Выбор ответа Middle Безопасность веб-приложения обновлено

Path traversal при отдаче файлов

Вопрос

Эндпоинт отдаёт open(os.path.join("/srv/files", name)), где name из запроса. Как атакуют и как защититься?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: name = "../../etc/passwd"; нормализовать путь и проверить, что он внутри каталога. os.path.join спокойно склеит .., а абсолютный путь в name вообще отбросит базовый каталог.

Варианты ответа

  1. Атаки нет: os.path.join сам отбрасывает .. и абсолютные пути из имени
  2. Достаточно запретить символ / в имени, тогда выйти из каталога нельзя
  3. name = "../../etc/passwd"; нормализовать путь и проверить, что он внутри каталогаправильный ответ
  4. Достаточно проверить расширение файла по белому списку: .pdf, .png, .jpg

Разбор

os.path.join спокойно склеит .., а абсолютный путь в name вообще отбросит базовый каталог. Надёжно: p = (BASE / name).resolve() и проверка p.is_relative_to(BASE) (Python 3.9+), а ещё лучше хранить файлы под сгенерированными id и не принимать пути от пользователя. Запрет / и проверка расширения обходятся.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме