2010-08-29 3 views
4

На платформе Linux, у меня есть C++ код, который идет как это: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.... 
  • Проходит вход пользователя в систему() называют безопасным на всех?
  • Следует ли избегать/дезинформировать пользователя?
  • Как?
  • Как этот код может быть использован для вредоносных целей?

Спасибо.

ответ

10

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

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

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

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

mkdir(myDir, someMode); 
+1

Обратите внимание, что 'execl' НЕ возвращает, если ошибка не возникает (в отличие от' system'). Сначала вам придется «форк», подождите в родительском процессе, чтобы ребенок завершил и в конечном итоге проверил возвращаемое значение 'execl' из родительского процесса. –

+0

Спасибо. если я использую mkdir (myDir, someMode), myDir не нужно дезинфицировать и избегать? Безопасно ли все, что вводит пользователь? – augustin

+0

Да, функция 'mkdir' C просто принимает имя каталога. Независимо от этого, он попытается создать единый каталог. –

2

Использование системы() вызов с параметрами командной строки без дезинфицирующего ввода может быть весьма небезопасно.

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

somedir ; rm -rf/

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

  • использования Getopt, чтобы обеспечить ввод в санированном
  • дезинфицировать ввод
  • использовать execl вместо системы для выполнения запятая й

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

+0

Спасибо за пример эксплойта. Это понятно! ;) Собственно, myDir приходит для getopt, хотя я не показывал его в коде выше. Я проверю, как использовать execl: видимо, нужна вилка (в соответствии с другим комментарием здесь). – augustin

+2

Не пытайтесь избежать строк И используйте execl - это приведет к передаче неправильных параметров. – MarkR

0

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

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

Смежные вопросы