在我正在处理的一个项目中,我们使用backtip方法来运行系统命令。
resp = `7z x #{zip_file_path} -p#{password} -o#{output_path}`
这很好用。但由于这可能会导致命令注入漏洞,我们计划使用exec
或open3
。使用open3
,我们在执行系统命令时面临问题。我们将此引用为解决命令注入问题。
stdin, stdout, stderr = Open3.popen3("7z", "x", zip_file_path, "-p", password, "-o", output_path)
但这导致低于误差
error = stderr.readlines
# ["n", "n", "Command Line Error:n", "Too short switch:n", "-on"]
当我包括这样的参数时,这是有效的。
stdin, stdout, stderr = Open3.popen3("7z", "x", zip_file_path, "-p#{password}", "-o#{output_path}")
但是,我们不应该单独传递参数以避免命令注入吗?或者我在第一个版本上做错了什么?
您的第二个版本(有效的版本(:
stdin, stdout, stderr = Open3.popen3("7z", "x", zip_file_path, "-p#{password}", "-o#{output_path}")
非常安全。由于不涉及shell,因此除了7z
本身之外,没有任何内容可以解释password
和output_path
。
不幸的是,7z
解析开关的方式很奇怪。通常情况下,您希望通过说-p xyz
和-pxyz
是-p -x -y -z
的缩写来将参数传递给开关。当你说:
Open3.popen3("7z", "x", zip_file_path, "-p", password, "-o", output_path)
这就像在壳里说:
7z x zip_file_path -p password -o output_path
但7z
不喜欢这些空间,它想要:
7z x zip_file_path -ppassword -ooutput_path
所以你需要做一些字符串插值。即便如此,Open3
没有外壳,因此没有注入。