我需要从嵌入到另一个 Mac/Windows 应用程序中的 Lua 解释器运行一些 shell 命令,其中 shell 命令是实现某些事情的唯一方法,比如在浏览器中打开帮助页面。如果我有一个参数列表(可能是用户输入的结果),我该如何转义每个参数以防止出现问题?
灵感来自 this article一个简单的解决方案似乎是转义所有非字母数字字符,在类 Unix 系统上使用 \
, 在 Windows 上 ^
.据我所知,这可以防止任何争论导致
- 由于插入换行符而执行另一个命令,
;
(Unix) 或&
( window ) - Unix 上的命令替换为
$
或`
- Windows 上的变量评估
%
- 重定向
<
,|
和>
此外,任何在相应平台上用作转义字符的字符都将被正确转义。
这对我来说似乎很合理,但是有没有我可能错过的陷阱?我知道在 bash 中,\
后跟一个换行符将有效地删除换行符,这在这里不是问题。
编辑
我的结论:没有一种机制可以通过交换转义字符同时在 Windows 和 *nix 上工作。事实证明,确保 Windows 程序实际看到我们希望它看到的命令行参数并不是那么简单,因为在 Windows 上将命令字符串拆分为参数不是由 shell 处理,而是由被调用程序本身处理。
因此需要考虑两层转义:
- 首先,Windows shell 将处理我们提供给它的内容。它可能做的是在
%
处进行变量替换。 , 在&
处拆分为多个命令或管道到|
处的另一个命令. - 然后,它会将单个命令字符串传递给程序将拆分的被调用程序,理想情况下但不一定遵循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/