0

在我正在处理的一个项目中,我们使用 backtip 方法来运行系统命令。

resp = `7z x #{zip_file_path} -p#{password} -o#{output_path}`

效果很好。但由于它可能导致命令注入漏洞,我们计划使用execopen3. 我们在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", "-o\n"]

当我包含这样的参数时,这有效。

stdin, stdout, stderr = Open3.popen3("7z", "x", zip_file_path, "-p#{password}", "-o#{output_path}")

但是我们不应该单独传递参数以避免命令注入吗?还是我对第一个版本做错了什么?

4

1 回答 1

4

您的第二个版本(有效的版本):

stdin, stdout, stderr = Open3.popen3("7z", "x", zip_file_path, "-p#{password}", "-o#{output_path}")

非常安全。password不涉及外壳,因此output_path除了自身之外没有任何东西可以解释7z


不幸的是7z,有一种奇怪的解析开关的方式。通常,您希望通过说-p xyzand-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所以没有注射。

于 2021-12-11T09:23:00.907 回答