← Все комнаты Путь «Защита (код)» →
СложныйЗащита (код) Код Осенний CTF

Без выхода за каталог

Прогресс комнаты 0 / 4
Задание 1Введение

Цель: Защищаться от path traversal при работе с файлами.

Напишите функцию safe_join(base, path) — защиту от path traversal. base — абсолютный путь без слэша в конце (например /var/www/files), path — путь от пользователя.

  • если в path есть нулевой байт — None;
  • обратные слэши \ считаются разделителями /;
  • путь, начинающийся с /, — None;
  • пустые части и . пропускаются, .. удаляет предыдущую часть;
  • если .. пытается выйти выше base — None.

Иначе верните base + / + нормализованный путь (или просто base, если путь пуст). URL-кодирование не раскрывайте — %2e%2e это обычное имя.

Задание 2Теория и инструменты

Path traversal — когда пользователь передаёт ../../etc/passwd и выходит за пределы разрешённого каталога.

Наивные фильтры (удалить ../) обходятся вариантами ....//, обратными слэшами и абсолютными путями. Надёжный способ — нормализовать путь самому и проверить, что он остался внутри базового каталога.

Инструменты

  • Python: split, список как стек
  • JS: split, push/pop

Больше теории — в разделе «Обучение: Защита (код)».

Задание 3Практика: напишите код

Примеры

Пример 1
safe_join("/var/www/files", "docs/readme.txt")
→ "/var/www/files/docs/readme.txt"
Пример 2
safe_join("/var/www/files", "../etc/passwd")
→ null
Пример 3
safe_join("/var/www/files", "a/b/../../c.txt")
→ "/var/www/files/c.txt"

Ещё 15 скрытых тестов.

solution
Ctrl+Enter — отправить Войдите, чтобы отправить

Пошаговый план — открывайте по одному шагу

  1. 1
    Сразу отклоните нулевой байт и пути, начинающиеся с / (после замены \ на /).

Подсказки — каждая до решения стоит −50 очков

Задание 4Как защититься

В Python — os.path.realpath + проверка префикса, во Flask — send_from_directory, safe_join из werkzeug. Не передавайте пользовательские пути напрямую в файловые функции.

Разборы участников

Разборы открываются после того, как вы решите комнату, — чтобы не спойлерить ответ.