Очистка пути в C ++ - PullRequest
       40

Очистка пути в C ++

4 голосов
/ 12 июня 2009

Я пишу небольшой доступный только для чтения FTP-подобный сервер. Клиент говорит «дай мне этот файл», и мой сервер отправляет его.

Есть ли какой-нибудь стандартный способ (библиотечная функция?!?), Чтобы убедиться, что запрошенный файл не "../../../../../etc/passwd" или что-то другое ? Было бы здорово, если бы я мог ограничить все запросы каталогом (и его подкаталогами).

Спасибо!

Ответы [ 6 ]

17 голосов
/ 12 июня 2009

Chroot - это, вероятно, лучший способ, но вы можете использовать realpath(3), чтобы определить канонический путь к заданному имени файла. Со страницы руководства:

 char *realpath(const char *file_name, char *resolved_name);

Функция realpath () разрешает все символические ссылки, дополнительные символы '/' и ссылки на /./ и /../ в имени файла и копирует полученный абсолютный путь в память, на которую ссылается разрешенное имя. Аргумент resolved_name должен ссылаться на буфер, способный хранить как минимум символы PATH_MAX.

Оттуда вы можете ограничить запрос любым дополнительным способом.

5 голосов
/ 12 июня 2009

Также взгляните на chroot

3 голосов
/ 12 июня 2009

Хотя это и не идеально, вы можете запустить свой ftp-сервер под определенным пользователем / группой и разрешить только определенные каталоги этому пользователю / группе. Это, однако, может быть не совсем то, что вы ищете.

У вас также может быть белый список каталогов, в которые пользователи могут переходить, и любые другие, к которым они пытаются перейти, вы просто не разрешаете (таким образом, в основном создавая свои собственные разрешения).

Лично я предпочитаю первое, так как эта работа уже сделана для вас ОС.

1 голос
/ 12 июня 2009

В Windows я бы сделал что-то вроде (все еще относится к любой ОС):

  1. Файл пользовательских запросов
  2. Сервер находит файл
  3. Сервер проверяет, начинается ли path_to_file с "C: / SomeFolderWithFiles /"
  4. Завершение транзакции
1 голос
/ 12 июня 2009

Получить индекс корневого каталога (/) и индекс обслуживающего каталога (скажем, / ftp / pub). Для файлов, которые они запрашивают, убедитесь, что:

  1. Файл существует.
  2. Родители файла (доступ к которому осуществляется через несколько символов "/ .." в пути к файлу) попадают на индекс обслуживающего каталога, прежде чем он попадет на индекс корневого каталога.

Вы можете использовать stat, чтобы найти индекс любого каталога. Поместите это в одну функцию и вызовите ее перед обработкой файла.

Конечно, использование пользователя / группы с соответствующими привилегиями также будет работать.

1 голос
/ 12 июня 2009

Я не знаю стандартной библиотеки, которая бы выполняла это.

Вы можете попробовать:

  1. Установите права пользователя unix, который работает на сервере, на то, чтобы он имел права только на чтение / запись для определенного каталога. (возможно, используя PAM, chrooted окружение или используя стандартные разрешения пользователя / группы unix)

  2. Вы можете разработать свою программу так, чтобы она принимала только абсолютные пути (в unix - пути, начинающиеся с '/'). Таким образом, вы можете проверить, чтобы убедиться, что это правильный путь - например, запретить любой путь со строкой ".."

редактирование:

С Питер : похоже, есть библиотечная функция, realpath () , которая помогает с # 2 сверху.

...