Как сделать eval безопасным?

Вопрос или проблема

Я пишу shell скрипт, который изменяет свое поведение в зависимости от количества переданных позиционных параметров

script.sh

if [ $# -eq 1 ]; then
  if [ -f "$1" ]; then
    validate="validate <"$1""
  else
    validate="validate <<<"$1""
  fi

else
  IFS=$'\n'
  validate="validate <<<'${*}'"
fi

eval "$validate" | pull_data

И validate, и pull_data — это функции Bash, которые читают из stdin и пишут в stdout

Если первый случай [ $# -eq 1 ], я считаю, что код безопасен от инъекций. Поскольку строка находится в одинарных кавычках, расширение параметра происходит только после вызова eval. Я не могу придумать строку, которая могла бы привести к инъекции кода здесь.

Проблема

Проблема возникает с условием else. Здесь каждый позиционный параметр расширяется в новую строку. Например

./script.sh "string_with_'_in_its_name" "code injected'"

Кавычка внутри одного из первых параметров вызывает интерпретацию последующих новых параметров как команд. Аналогично это также приводит к уязвимости инъекции:

./script.sh valid_input \''$(code injected)'\'

Контекст

Я использую eval, чтобы избежать повторения конструкции validate ... | pull_data в каждом условии if. Настоящий скрипт имеет гораздо больше условий, и использование eval делает его более читаемым.

Любые советы о том, как переработать этот скрипт, чтобы избежать проблемы инъекции при сохранении удобочитаемости, будут очень признательны!

Ответ или решение

Чтобы обеспечить безопасность использования команды eval в вашем скрипте, очень важно принимать меры предосторожности для предотвращения возможности инъекций кода. Проблемы, которые вы описали, действительно могут привести к уязвимостям, если использовать eval небезопасно. Давайте разберемся, как можно решить эти проблемы, сохраняя читаемость вашего скрипта.

Проблема

Использование eval приводит к выполнению строки как команды в оболочке. В вашем скрипте это может вызвать уязвимость, если параметры могут не так интерпретироваться, как ожидалось. В частности, когда вы передаете параметры, содержащие специальные символы или апострофы, это может привести к инъекции кода.

Решение

  1. Избегайте использования eval, если это возможно. Попробуйте изменить архитектуру скрипта так, чтобы eval не использовался вовсе. Например, вместо динамического построения строки с eval, вы можете использовать функции или прямую проверку условий и вызов нужных функций.

  2. Используйте массивы. Если вы вынуждены использовать eval из-за архитектуры кода, используйте массивы и безопасные функции обработки строк. Массивы позволяют сохранить параметры скрипта, избегая необходимости в eval.

  3. Более безопасные альтернативы. Для аналогичной функциональности можно использовать xargs или set для безопасного управления параметрами. Это позволяет избежать необходимости использовать eval для обработки изменений параметров.

  4. Экранирование параметров. Убедитесь, что все параметры, передаваемые в eval, тщательно экранируются, чтобы избежать интерпретации нежелательных символов как команд оболочки. Однако следует заметить, что экранирование не всегда может защитить от всех возможных уязвимостей, особенно когда речь идет о сложных строках.

  5. Контекстуальная проверка. Добавьте строгие проверки входных данных на этапе валидации. Разработайте алгоритм для проверки каждого параметра функции validate до того, как она попадет в eval.

Рефакторинг

Ваш скрипт можно переписать без eval, используя конструкции управления потоком или расширенные условные выражения, чтобы более безопасно обрабатывать логические ветки:

if [ $# -eq 1 ]; then
  if [ -f "$1" ]; then
    validate < "$1"
  else
    validate <<< "$1"
  fi
else
  for param in "$@"; do
    validate <<< "$param"
  done
fi | pull_data

Здесь мы избегаем использования eval и манипулируем параметрами напрямую, что делает код более безопасным и менее подверженным уязвимостям.

Заключение

Безопасность — это приоритетная задача при работе со скриптами, особенно при обработке входных данных. Следуя вышеописанным рекомендациям, вы сможете создать более безопасный и надежный скрипт без eval, сохраняя при этом его читаемость и эффективность.

Оцените материал
Добавить комментарий

Капча загружается...