Ruby 使用 open3 防止命令注入
Ruby prevent command injection with open3
在我正在处理的项目之一中,我们对 运行 系统命令使用了 backtip 方法。
resp = `7z x #{zip_file_path} -p#{password} -o#{output_path}`
效果很好。但由于它可能导致命令注入漏洞,我们计划使用 exec
或 open3
。 open3
我们在执行系统命令时遇到问题。我们参考 this 来解决命令注入问题。
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", "-o\n"]
当我包含这样的参数时,这会起作用。
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)
这就像在 shell 中这样说:
7z x zip_file_path -p password -o output_path
但是7z
不喜欢那些空间,它想要:
7z x zip_file_path -ppassword -ooutput_path
所以您无法进行一些字符串插值。即便如此,Open3
没有涉及 shell,所以没有注入。
在我正在处理的项目之一中,我们对 运行 系统命令使用了 backtip 方法。
resp = `7z x #{zip_file_path} -p#{password} -o#{output_path}`
效果很好。但由于它可能导致命令注入漏洞,我们计划使用 exec
或 open3
。 open3
我们在执行系统命令时遇到问题。我们参考 this 来解决命令注入问题。
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", "-o\n"]
当我包含这样的参数时,这会起作用。
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)
这就像在 shell 中这样说:
7z x zip_file_path -p password -o output_path
但是7z
不喜欢那些空间,它想要:
7z x zip_file_path -ppassword -ooutput_path
所以您无法进行一些字符串插值。即便如此,Open3
没有涉及 shell,所以没有注入。