flawopen.com/Command Injection/Java Runtime.exec()
Защищает ли Java Runtime.exec() от Command Injection?
Runtime.exec(String) не запускает shell автоматически, поэтому операторы shell не интерпретируются им как команды. Но строка всё равно разбивается на программу и аргументы, и недоверенный текст может изменить аргументы целевой программы. ProcessBuilder явно задаёт границы аргументов; при этом необходимо проверять каждое значение и ограничить исполняемый файл и допустимые параметры.
// Пользовательский ввод добавляется к строке команды Runtime.getRuntime().exec( "approved-tool --input " + filename );
// Фиксированная программа и отдельные аргументы; сначала проверьте filename String safeName = validateFilename(filename); new ProcessBuilder( "/opt/app/bin/approved-tool", "--input", safeName ).start();
Инъекция в shell и инъекция аргументов — разные угрозы
Начиная с Java 18, Oracle помечает Runtime.exec(String) как устаревший из-за склонности к ошибкам и рекомендует exec(String[]) или ProcessBuilder. Строковая перегрузка делит команду по пробельным символам, поэтому, например, путь с пробелами может распасться на части. Runtime.exec(String) не запускает автоматически sh или другую оболочку; Oracle указывает, что строка преобразуется в массив аргументов. Поэтому обычные метасимволы shell не становятся синтаксисом оболочки, но ввод всё ещё опасен: токенизация может создать дополнительные аргументы, а целевая программа способна трактовать аргумент как опцию. ProcessBuilder принимает список строк с программой и аргументами; на распространённых платформах каждый элемент задаёт границу аргумента. Зафиксируйте исполняемый файл, проверяйте значения по ожидаемому формату программы и отклоняйте или безопасно обрабатывайте значения, похожие на опции. Используйте -- только если документация программы гарантирует такое поведение. Не запускайте оболочку явно, например через sh -c, с недоверенными данными.
Частые вопросы
Нет. Это снижает риск инъекции в shell для данной перегрузки, но инъекция аргументов остаётся возможной. Программа может принять ввод атакующего за опцию или имя файла. Используйте ProcessBuilder с фиксированной программой и отдельными аргументами и проверяйте каждое значение с учётом целевой программы.
Нет. Он формирует список программы и аргументов и запускает процесс, но не проверяет их безопасность и допустимость. Добавьте списки разрешённых значений и проверку в приложении и соблюдайте документированные правила аргументов программы.