Path traversal — это уязвимость, возникающая при неправильной обработке пользовательских входных данных. Злоумышленник может читать файлы за пределами целевого каталога, получая доступ к конфигурационным файлам, скриптам или базам данных. Защита строится на принципе: никогда не доверяйте данным извне и всегда валидируйте их.
Защита файловых эндпоинтов от path traversal: суть угрозы и механизм атаки
Атака path traversal (или directory traversal) позволяет злоумышленнику выйти за пределы разрешенной директории приложения. Это достигается путем подмены параметров пути в URL-запросе.
Механизм прост: если приложение ожидает путь к файлу, например, /images/logo.png, а пользователь передает в запросе ../etc/passwd (в Linux) или ..\..\windows\system32\config\sam (в Windows), сервер может интерпретировать эти символы как инструкцию перейти на уровень выше. В результате приложение начинает читать файлы из корневой директории сервера.
Чем опасен такой доступ: злоумышленник может скачать .env-файлы с паролями, конфигурационные файлы веб-сервера (nginx.conf, httpd.conf), исходный код приложения или базы данных. В худшем случае это позволяет выполнить произвольный код на сервере.
Угроза актуальна для любых приложений, предоставляющих доступ к файлам: CMS с функцией загрузки файлов, системы управления документами, API для работы с медиа-контентом и пользовательскими аватарами.
Валидация входных данных: принцип белого списка и санитизация путей
Основной метод защиты — строгая валидация всех входящих параметров, содержащих пути. Никогда не полагайтесь на то, что пользователь предоставит корректный путь.
Используйте принцип «белого списка» (whitelist). Определите список разрешенных префиксов путей (например, /uploads/, /images/) и проверяйте, начинается ли полученный путь именно с них. Если нет — отклоняйте запрос.
Пример логики на псевдокоде:
allowed_prefix = '/uploads/'
user_path = request.path
if not user_path.startswith(allowed_prefix):
return error('Forbidden')
Санитизация путей: перед использованием пути в системе файлов, нормализуйте его. Удалите избыточные разделители (//), сократите точки (./) и убедитесь, что путь не содержит символов .. или \..\. Это предотвращает обход через двойные точки.
Важно: санитизация не заменяет проверку белого списка. Даже после нормализации нужно убедиться, что результат находится в разрешенной зоне.
Использование безопасных функций языка программирования для работы с путями
Не используйте функции типа open(path) или file_get_contents(path) напрямую с данными из запроса. Используйте встроенные механизмы безопасности языков.
В Python используйте os.path.realpath() или pathlib.Path.resolve() для получения абсолютного пути, но только после проверки, что он находится внутри целевой директории. Функция resolve() сама нормализует путь, но не защищает от выхода за пределы, если не добавить проверку is_relative_to().
В PHP используйте realpath() для получения канонического пути и проверяйте его с помощью strpos(), чтобы убедиться, что он начинается с разрешенного префикса.
В Java используйте Path.normalize() и проверьте, является ли полученный путь подкаталогами базового пути через startsWith().
Избегайте функций, позволяющих интерпретировать переменные как команды (command injection), если они используются в контексте работы с файлами.
Настройка прав доступа к файловой системе на уровне ОС и веб-сервера
Даже при наличии уязвимости код, защищенный правильными правами доступа, не позволит злоумышленнику получить чувствительные данные.
Установите права 755 (rwxr-xr-x) для директорий и 644 (rw-r—r—) для файлов. Это означает, что другие пользователи могут только читать файлы, но не изменять их или выполнять код внутри них.
Настройте веб-сервер (Nginx/Apache) так, чтобы он не мог исполнять скрипты в директориях для хранения статического контента. В Nginx это делается через директиву index и запретом на выполнение скриптов в определенных папках.
Используйте chroot или контейнеризацию (Docker), чтобы ограничить доступ приложения к файловой системе всего сервера. Приложение будет видеть только виртуальную корневую директорию, где нет критических системных файлов.
Реализация лимитов глубины вложенности (depth limits) для рекурсивного обхода
Если ваше приложение поддерживает рекурсивный поиск или навигацию по папкам, ограничьте максимальную глубину вложенности.
Например, разрешите переход не более чем на 3 уровня вверх от корня директории. Это предотвращает глубокий обход через многослойные структуры.
В коде это реализуется путем подсчета количества разделителей .. в нормализованном пути или ограничения длины относительного пути.
Пример: если разрешенная глубина 3, а путь содержит 5 переходов вверх — запрос отклоняется.
Мониторинг и логирование подозрительных попыток доступа к файлам
Ведите логи всех обращений к файловой системе, особенно тех, что касаются чувствительных директорий.
Ищите в логах паттерны, характерные для path traversal: наличие .., \..\, %2e%2e и других вариаций. Многие атакующие используют URL-кодирование символов.
Настройте алерты на веб-сервере или в системе мониторинга (например, ELK Stack) при обнаружении таких паттернов. Это позволит быстро реагировать на попытки эксплуатации уязвимости.
Анализ логов помогает выявить не только активные атаки, но и автоматизированные сканеры, которые перебирают возможные пути.
Регулярное обновление зависимостей и патчинг известных уязвимостей путей
Многие библиотеки для работы с файлами имеют известные уязвимости path traversal. Регулярно обновляйте зависимости (npm, pip, maven, composer).
Используйте инструменты сканирования уязвимостей (например, Snyk, Dependabot) для выявления проблемных библиотек.
Если вы используете сторонние модули для загрузки файлов, проверяйте их документацию на наличие предупреждений о безопасности и следуйте рекомендациям разработчиков.
Не игнорируйте патчи от производителей ПО — они часто содержат исправления именно таких уязвимостей.
Тестирование на path traversal: методы проверки защиты без риска для продакшена
Перед выпуском обновлений тестируйте защиту от path traversal в среде, идентичной продакшену, но изолированной.
Используйте инструменты автоматизированного тестирования (например, OWASP ZAP, Burp Suite) для генерации запросов с паттернами атак.
Ручное тестирование: попробуйте отправить в URL следующие строки:
../../../etc/passwd
../../../../../../../etc/shadow
%2e%2e%2f%2e%2e%2fetc%2fpasswd
Убедитесь, что сервер возвращает ошибку 403 или 404, а не контент файла. Если файл загружается — защита нарушена.
Не проводите тесты на реальном сайте без отключения записи логов и мониторинга, чтобы избежать ложных срабатываний.
Вопросы и ответы
Можно ли полностью исключить path traversal?
Полностью исключить нельзя, но можно свести риск к минимуму. Угроза существует везде, где есть доступ к файлам извне. Защита строится на комбинации валидации, прав доступа и мониторинга.
Нужно ли проверять пути только при загрузке файлов?
Нет. Проверка нужна каждый раз, когда путь используется для чтения или записи файла. Даже если файл загружен ранее, доступ к нему должен быть защищен.
Как отличить path traversal от легитимного доступа к файлам?
Легитимный доступ всегда начинается с разрешенного префикса (например, /uploads/). Если путь содержит .. или выходит за пределы этого префикса — это атака.


