在 bash 中安全地读取和解析参数或文件中的字符串

在 bash 中安全地读取和解析参数或文件中的字符串

我最近一直在编写一些 bash 脚本,它们从参数或文件中获取变量。一些脚本以 root 身份运行(使用 sudo)

这是在我的笔记本上,因此在这种情况下没有任何其他用户会导致安全问题,但是......

我希望能够编写一个可以发布到野外的脚本。

也许,这个问题的作用是为不在涉及 root/sudo 且输入/参数不可信的 bash 中编写任何内容提供强有力的理由。

除了用 sudoers 锁定所有内容之外,还有没有办法将任意字符串读入 bash 程序并解析它没有允许 bash 扩展它,并可能沿途执行某些操作?

我没有看到任何防御流氓参数的解决方案。

对于文件来说,也许有办法,但并不简单。

该字符串可以使用 read 安全地输入到脚本中,但是一旦它位于一个或多个变量中,我就看不到任何不涉及潜在危险的变量扩展的访问它的方法。

我认为可以使用 read -n 1 从文件中读取数据,以便在循环中一次将一个字符放入数组中。这应该可以消除任何东西,但是稍后必须一个字符一个字符地重新组装所有内容,这有点麻烦。

我正在考虑这样的输入:

'$(rm -rf ./*)' 或 'eval shutdown -h now'

或类似的输入作为输入,当引用包含它的变量时将运行。如果脚本以 root 身份运行,这可能是一个真正的问题!

除了“获得真正的编程语言”之外,还有关于如何解决此问题的任何想法吗?

答案1

如果不知道该文件中必须提供什么样的信息,就很难回答这个问题。脚本存储在具有多个用户的系统上并不自动成为安全问题。为什么他们应该(能够)为其他用户提供输入?

但是,您可以通过 安全地从文件中读取一行read -r line。如果您只需要此类数据,foo=bar那么您可以通过 轻松检查该行是否存在无效字符(或结构)[[ =~ ]]

如果您不限于使用单个文件,那么可以从 DJB 软件中获取一个简单的解决方案:每个变量一个文件。然后可以通过以下方式定义变量:

for varname in ${vars[@]}; do
  if [ -f "${path_to_var_files}"/$varname ]; then
    eval $varname='"$(cat '"${path_to_var_files}"/$varname"')"'
  fi
done

...如果尾随换行符不重要。

许多问题(对于系统,而不是对于相应的用户)可以通过最小化在 sudo 下运行的代码来解决。不要让 sudo 脚本获取该文件。让用户级脚本获取文件并进行 sudo 调用。 sudo 脚本应该有一个清晰的界面,易于检查输入。

相关内容