bash - 转义以防止正确的 shell 注入(inject)

标签 bash shell batch-file escaping code-injection

我需要从嵌入到另一个 Mac/Windows 应用程序中的 Lua 解释器运行一些 shell 命令,其中 shell 命令是实现某些事情的唯一方法,比如在浏览器中打开帮助页面。如果我有一个参数列表(可能是用户输入的结果),我该如何转义每个参数以防止出现问题?

灵感来自 this article一个简单的解决方案似乎是转义所有非字母数字字符,在类 Unix 系统上使用 \ , 在 Windows 上 ^ .据我所知,这可以防止任何争论导致

  • 由于插入换行符而执行另一个命令,; (Unix) 或 & ( window )
  • Unix 上的命令替换为 $`
  • Windows 上的变量评估 %
  • 重定向 < , |>

此外,任何在相应平台上用作转义字符的字符都将被正确转义。

这对我来说似乎很合理,但是有没有我可能错过的陷阱?我知道在 bash 中,\后跟一个换行符将有效地删除换行符,这在这里不是问题。

编辑

我的结论:没有一种机制可以通过交换转义字符同时在 Windows 和 *nix 上工作。事实证明,确保 Windows 程序实际看到我们希望它看到的命令行参数并不是那么简单,因为在 Windows 上将命令字符串拆分为参数不是由 shell 处理,而是由被调用程序本身处理。

因此需要考虑两层转义:

  1. 首先,Windows shell 将处理我们提供给它的内容。它可能做的是在 % 处进行变量替换。 , 在 & 处拆分为多个命令或管道到 | 处的另一个命令.
  2. 然后,它会将单个命令字符串传递给程序将拆分的被调用程序,理想情况下但不一定遵循rules described by Microsoft。 .

假设它遵循这些规则,就可以向后工作,首先转义到这些规则,然后进一步转义到 shell。

最佳答案

使用动态参数调用子流程容易出错和危险,而且许多语言没有提供良好的机制来保护开发人员。例如,在 Python 中,os.system()不再推荐,而是 subprocess模块为安全地进行系统调用提供了适当的机制。特别是,您向 subprocess.run() 传递了一个参数列表,而不是单个字符串,从而避免了首先需要实现任何容易出错的转义。

快速搜索类似 subprocess 的 Lua 工具,发现 lua-subprocess ,它似乎没有被积极开发,但可能仍然比尝试自己实现适当的转义更好。

如果您必须这样做,请查看 shlex.quote() 的 Python 代码( source ) - 它正确地转义输入字符串以便“在 shell 命令行中”使用:

# use single quotes, and put single quotes into double quotes
# the string $'b is then quoted as '$'"'"'b'
return "'" + s.replace("'", "'\"'\"'") + "'"

您应该能够在 Lua 中复制它。

关于bash - 转义以防止正确的 shell 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34898430/

相关文章:

mysql - 读取用户输入并将其发送到 MySQL

bash - Symfony 2 和 3+ 版本的控制台命令别名

linux - 如何在 Linux Shell 中将文件的创建日期和最后修改日期更改为当前时间?

Python:在外部 shell 中进行的定义获得错误的 `.__module__` 属性

batch-file - 批处理文件执行命令前加1

linux - 为什么 grep 搜索 '0,^M$' 返回空行?

linux - .sh 脚本没有正确返回变量

linux - 如何将多行 bash 代码粘贴到终端并一次运行?

android - 如何使用adb push填充SD卡

batch-file - 在打开 Internet Explorer 选项卡之前运行 tomcat