Bash 为防止外壳注入而逃逸
我需要从嵌入到另一个Mac/Windows应用程序中的Lua解释器运行一些shell命令,在这个应用程序中,shell命令是实现某些事情的唯一方法,比如在浏览器中打开帮助页。如果我有一个参数列表(这可能是用户输入的结果),我如何能避开每个参数以避免麻烦 受一个简单解决方案的启发,在类Unix系统上使用Bash 为防止外壳注入而逃逸,bash,shell,batch-file,escaping,code-injection,Bash,Shell,Batch File,Escaping,Code Injection,我需要从嵌入到另一个Mac/Windows应用程序中的Lua解释器运行一些shell命令,在这个应用程序中,shell命令是实现某些事情的唯一方法,比如在浏览器中打开帮助页。如果我有一个参数列表(这可能是用户输入的结果),我如何能避开每个参数以避免麻烦 受一个简单解决方案的启发,在类Unix系统上使用\,在Windows上使用^时,似乎可以转义所有非字母数字字符。据我所知,这防止了任何争论会导致 由于插入换行符,,执行另一个命令(Unix)或&(Windows) 在Unix上使用$或` 在具有
\
,在Windows上使用^
时,似乎可以转义所有非字母数字字符。据我所知,这防止了任何争论会导致
- 由于插入换行符,
,执行另一个命令代码>(Unix)或
(Windows)&
- 在Unix上使用
或$
`
- 在具有
%
- 使用
\
后跟换行符将有效地删除换行符,这在这里不是问题
编辑
我的结论是:没有一种机制可以通过交换转义字符同时在Windows和*nix上工作。事实证明,要确保Windows程序真正看到我们希望它看到的命令行参数并不是那么简单,因为将命令字符串拆分为Windows上的参数不是由shell处理的,而是由被调用的程序本身处理的
因此,需要考虑两层逃逸:
%
处进行变量替换,在&
处拆分为多个命令,或者在|
处连接到另一个命令假设它遵循这些规则,我们可以逆向工作,首先转义到这些规则,然后再转义到shell。使用动态参数调用子进程容易出错和危险,而且许多语言都没有提供良好的机制来保护开发人员。例如,在Python中,不再推荐使用该模块,而是提供了一种适当的机制来安全地进行系统调用。特别是,您可以传递
subprocess.run()
参数列表,而不是单个字符串,从而避免了首先需要实现任何容易出错的转义
快速搜索类似于子流程的Lua工具,该工具似乎没有得到积极开发,但可能比自己尝试实现正确的转义要好
如果必须这样做,请查看()的Python代码—它正确地转义了一个输入字符串,以便“在shell命令行中”使用:
你应该能够在Lua中复制这一点。这就是为什么你不应该被一个显然不熟悉bash的人写的随机博客文章“启发”的原因。你应该做的是RTFM:你会意识到用反斜杠引用所有东西不仅是过火,实际上还有一个例外,也就是说,你所做的是错误的。你应该做的是用'\''
替换每一个引号,然后用单引号将整个事情包装起来,然后用它来完成。顺便说一句,我特别对bash进行了评论。在同一个问题中询问bash和cmd并不是一个好主意。您将使用什么类型的windows batch或linux bash系统?解决方案完全不同在类Unix系统上创建进程,Windows则完全不同:类Unix系统使用execve
单独传递参数,而Windows在单个命令行字符串中传递参数。尽管Windows上有解析命令行的指南和内置实用程序,但每个程序都可以制定自己的命令行解析规则。看看和。你为什么用贝壳?
# use single quotes, and put single quotes into double quotes
# the string $'b is then quoted as '$'"'"'b'
return "'" + s.replace("'", "'\"'\"'") + "'"