逃逸以防止正确的外壳注入

Tho*_*s W 6 bash shell escaping batch-file code-injection

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

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

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

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

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

编辑

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

因此需要考虑两层转义:

  1. 首先,Windows shell 将处理我们给它的东西。它可能做的是变量替换 at %,拆分为多个命令 at&或管道到另一个命令 at |
  2. 然后,它会将单个命令字符串传递给该程序将拆分的被调用程序,理想情况下但不一定遵循Microsoft 描述规则

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

dim*_*414 4

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

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

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

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

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