System () называет зло? - PullRequest
       0

System () называет зло?

16 голосов
/ 11 ноября 2011

Я разрабатываю приложение на C ++, которое, между прочим, время от времени выполняет несколько сценариев. Приложение должно быть эффективным и желательно независимым от платформы.

Однако проблема заключается в следующем: есть ли причина, по которой не следует использовать system() call для запуска скриптов и использовать, например, средства POSIX? Дискуссия по этому вопросу, которую я видел до сих пор, обычно сводится к:

  1. system() менее гибок. (Хорошо со мной)
  2. Не предлагает контроля над выполняемой командой. (Хорошо, мне просто нужно возвращаемое значение из скрипта)
  3. Это не совсем независимо от платформы. (Теперь это может быть проблемой. Мне бы очень хотелось увидеть пример, где он ведет себя по-разному на разных платформах)
  4. Это проблема безопасности. (Опять же, это может быть проблемой. Может ли кто-нибудь привести пример потенциальной проблемы безопасности с system()?)
  5. Есть еще вопросы?

Ответы [ 5 ]

5 голосов
/ 11 ноября 2011

3) Это не совсем независимо от платформы (Теперь, это было бы проблемой. Я действительно хотел бы видеть пример, где это ведет себя по-разному на разных платформах)

Ну,например, system("ls"), вероятно, потерпит неудачу в Windows, поскольку нет команды ls .

4) Это проблема безопасности.(Опять же, это может быть проблемой. Может ли кто-нибудь привести пример потенциальной проблемы безопасности с системой ()?)

Если аргумент, переданный system, поступает из пользовательского ввода, а не правильнопроверено, это может использоваться для выполнения нежелательных вещей с уровнями привилегий исходного исполнителя.Если это статический контент, его довольно легко найти в исполняемом образе и изменить, чтобы он тоже делал неприятные вещи.

3 голосов
/ 11 ноября 2011

(3) Если вы просто хотите получить контрпример, например, grep ведет себя по-разному в Solaris против Linux и любого другого.

(4) Права вашей программы наследуются порожденными ими программами. Если ваше приложение когда-либо запускается как привилегированный пользователь, все, что кому-то нужно, это поместить свою собственную программу с именем того, что вы тоже выкладываете, и затем может выполнить произвольный код (это означает, что вы никогда не должны запускать программу, использующую * 1003). * как root или setuid root).

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

1 голос
/ 03 марта 2015

Что касается вопросов безопасности, классическим примером (4) является следующий сценарий: представьте, что пользователю предлагается указать какое-то имя каталога для резервного копирования в std::string dirname; тогда вы вычислите какое-нибудь имя директории резервного копирования в std::string backup и выполните

system((std::string{"cp -a "} + dirname + " " + backup).c_str())

Теперь подумайте, что произойдет, если злонамеренный пользователь введет foo bar; rm -rf $HOME; ls в качестве dirname и backup будет /vol/backup_2015_fev/. Команда system будет выполнять

cp -a  foo bar; rm -rf $HOME; ls /vol/backup_2015_fev/

это не то, что вы ожидали (все $HOME пользователя будут удалены!). Это пример внедрения кода , и при использовании system вы должны убедиться, что этого никогда не произойдет (например, путем очистки и / или экранирования каждой строки, связанной с пользовательским вводом)

Кроме того, PATH может отличаться от того, что вы считаете (например, начиная с /tmp/ и злонамеренный пользователь сделал ln -s /bin/rm /tmp/cp до запуска system).

1 голос
/ 11 ноября 2011

Я поддерживаю систему, которая состоит из нескольких отдельных исполняемых файлов. В этом случае я контролирую разрешения, имена, соглашения о вызовах, безопасность всех поддерживаемых платформ. В этом случае system () работает просто отлично. Приложения взаимодействуют через СУБД.

Опять же, как и другие отмечали "Дьявол в деталях".

0 голосов
/ 11 ноября 2011

Я использовал вызов system () в своем приложении CGI C ++ для Windows и Linux.

Одна проблема, с которой я столкнулся, заключалась в том, что при использовании system () не было необходимых прав доступа для выполнения моего скрипта с помощьювеб-пользователь.

У меня больше не было этой проблемы при использовании метода CreateProcess ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...