C ++: Как избежать пользовательского ввода для безопасных системных вызовов? - PullRequest
4 голосов
/ 29 августа 2010

На платформе Linux у меня есть код C ++, который выглядит следующим образом:

// ...
std::string myDir;
myDir = argv[1]; // myDir is initialized using user input from the command line.
std::string command;
command = "mkdir " + myDir;
if (system(command.c_str()) != 0) {
   return 1;
}
// continue....
  • Безопасно ли вообще передавать пользовательский ввод в вызов system ()?
  • Должен ли пользовательский ввод быть экранирован или очищен?
  • Как?
  • Как можно использовать вышеуказанный код в злонамеренных целях?

Спасибо.

Ответы [ 3 ]

10 голосов
/ 29 августа 2010

Только не используйте system. Предпочитаю execl.

execl ("/bin/mkdir", "mkdir", myDir, (char *)0);

Таким образом, myDir всегда передается как один аргумент mkdir, и оболочка не задействуется. Обратите внимание, что вам нужно fork, если вы используете этот метод.

Но если это не просто пример, вы должны использовать функцию mkdir C:

mkdir(myDir, someMode);
2 голосов
/ 29 августа 2010

Использование вызова system () с параметрами командной строки без очистки входных данных может быть крайне небезопасным.

Потенциальной угрозой безопасности может быть пользователь, передающий в качестве имени каталога следующее:

somedir ; rm -rf /

Чтобы предотвратить это, используйте следующую смесь

  • используйте getopt, чтобы убедиться, что ваш ввод продезинфицировать
  • дезинфицировать вход
  • использовать execl вместо system для выполнения команда

Лучшим вариантом будет использовать все три

0 голосов
/ 29 августа 2010

В дополнение к ответу Мэтью не запускайте процесс оболочки, если он вам абсолютно не нужен.Если вы используете комбинацию fork / execl, отдельные параметры никогда не будут анализироваться, поэтому их не нужно экранировать.Однако остерегайтесь нулевых символов, которые по-прежнему преждевременно прерывают параметр (в некоторых случаях это не проблема безопасности).

Я предполагаю, что mkdir - всего лишь пример, так как mkdir можно тривиально вызвать из C ++ гораздо легчеэти предложения подпроцесса.

...