В этой статье мы узнаем, как правильно вызовать команды системы, используя node.js, чтобы избежать общих уязвимостей впрыска командной строки.
Метод, который мы часто используем для вызова команд, является самым простым Child_process.exec. У него очень простой шаблон использования; Он передает строку команду и передает результат обработки ошибки или командной обработки функции обратного вызова.
Вот очень типичный пример ваших команд вызовой системы через child_process.exec.
Кода -копия выглядит следующим образом:
child_process.exec ('ls', function (err, data) {
console.log (data);
});
Тем не менее, что происходит, когда вам нужно добавить некоторые параметры, включенные в пользователь, в команду, которую вы звоните? Очевидное решение - напрямую навязывать пользовательский ввод с вашей командой. Тем не менее, мой многолетний опыт говорит мне: когда вы отправляете подключенные струны из одной системы в другую, однажды будут проблемы.
Кода -копия выглядит следующим образом:
var path = "пользовательский ввод";
child_process.exec ('ls -l' + path, function (err, data) {
console.log (data);
});
Почему у строки соединения есть проблемы?
Ну, потому что под двигателем child_process.exec будет вызвано выполнение «/bin/sh». Не целевая программа. Присланная команда только что передается в новый процесс "/bin/sh 'для выполнения оболочки. Имя child_process.exec несколько вводит в заблуждение - это интерпретатор Bash, а не программа. Это означает, что все символы оболочки могут иметь разрушительные последствия, если параметры, введенные пользователем, выполняются напрямую.
Кода -копия выглядит следующим образом:
[PID 25170] execve ("/bin/sh", ["/bin/sh", "-c", "ls -l пользовательский ввод"], [/ * 16 vars */]
Например, злоумышленник может использовать полуколон ";"; ";"; ";"; ";"; ";"; Чтобы закончить команду и запустить новый звонок, и они могут использовать бэктики или $ () для запуска подкоманда. Есть также много потенциальных злоупотреблений.
Так как же это правильный способ назвать это?
execfile / spawn
Spawn и Execfile принимают дополнительный параметр массива, который не является средой оболочки, которая может выполнять другие команды и не будет выполнять дополнительные команды.
Давайте использовать ExecFile и Spawn, чтобы изменить предыдущий пример, чтобы увидеть, как различаются системы системных вызовов и почему он не подвержен инъекции команды.
child_process.execfile
Кода -копия выглядит следующим образом:
var child_process = require ('child_process');
var path = "."
child_process.execfile ('/bin/ls', ['-l', path], function (err, result) {
Console.log (результат)
});
Запуск системных вызовов
Кода -копия выглядит следующим образом:
[PID 25565] execve ("/bin/ls", ["/bin/ls", "-l", "."], [/ * 16 vars */]
child_process.spawn
Примеры использования замены спауна очень похожи.
Кода -копия выглядит следующим образом:
var child_process = require ('child_process');
var path = "."
var ls = child_process.spawn ('/bin/ls', ['-l', path])
ls.stdout.on ('data', function (data) {
console.log (data.toString ());
});
Запуск системных вызовов
Кода -копия выглядит следующим образом:
[PID 26883] execve ("/bin/ls", ["/bin/ls", "-l", "."], [/ * 16 vars */
При использовании Spawn или Execfile наша цель - выполнить только одну команду (параметр). Это означает, что пользователь не может запустить инъецированную команду, потому что /bin /ls не знает, как обрабатывать обратные вызовы или трубы или;. Что его /bin /bash объяснит, это параметры этих команд. Он похож на использование параметра для передачи параметров в запрос SQL, если вы знакомы с ним.
Но есть также предупреждение: использование Spawn или Execfile не всегда безопасно. Например, запуск /bin /find и передача параметров ввода пользователя все еще может привести к ловушке системы. Команда Find имеет некоторые параметры, которые позволяют чтение/написание произвольных файлов.
Итак, вот несколько рекомендаций по node.js, работающему системными командами:
Избегайте использования child_process.exec, особенно если вам нужно включить параметры, введенные пользователем, помните.
Старайтесь не позволять пользователям передавать параметры. Использование выбора намного лучше, чем привлекать пользователей напрямую вводить строки.
Если вам нужно разрешить пользователю вводить параметры, широко см. Параметры команды, определите, какие параметры безопасны, и создайте белый список.