当用作cgi-bin时,如何使用setuid()成功运行Perl脚本?

时间:2011-02-14 10:19:37

标签: perl apache cgi-bin setuid suexec

我有一个Perl脚本,可以通过Apache或命令行调用。

出于测试目的,我将其传递给我希望Perl脚本运行的用户名,并使用POSIX::setuid设置uid

如果我从命令行运行脚本,则uid设置正确:

use CGI::Pretty qw/:standard/;
use POSIX qw(setuid getuid);

...
my ($pwName, $pwCode, $pwUid, $pwGid, $pwQuota, $pwComment, 
    $pwGcos, $pwHome, $pwLogprog) = getpwnam($username);

if ((defined $pwUid) && (getuid() == $pwUid)) {
    setuid($pwUid);
    print header;
    print Dumper $<;
}
else {
    print header(-status => 401);
    print "Could not setuid to correct uid (currently: )".getuid()."\n";
}

命令行输出显示指定uid的正确$username,而不是开始运行脚本的测试帐户的uid

如果我通过Apache调用脚本,那么uid仍会设置为apache用户的ID,并且永远不会更改。

我不相信我可以在这里使用suExec,因为在阅读文档之后:

  1. 我无法将此脚本的副本放入http://www.example.com/~username$username。该脚本需要从一个位置运行,我需要在脚本中指定uid

  2. 我需要在运行时将脚本作为指定的用户名运行,而不是在Apache配置文件中的虚拟主机指令中指定的单个用户名。每次新用户运行此脚本时,更改此配置文件并重新启动Apache都是不现实的。

  3. 在使用uid时,如何将Perl脚本作为cgi-bin运行以正确更改setuid()

1 个答案:

答案 0 :(得分:4)

setuid对任意uid的唯一方法是以root身份运行。[1]

我不了解你,但以root身份运行CGI程序的想法让我做恶梦。

更改uid后,这段代码应该实际执行什么操作?也许有一种方法可以实现这一点,而不必setuid

[1]根据您的代码及其安全模型,您可以收集用户的密码并使用su / sudo [2]运行单独的命令行程序来运行Web服务器环境之外的实际操作,但su / sudo能够执行此操作,因为它们是suid root并且仍然会打开与运行CGI代码相关的大多数/所有问题无论如何,作为根。即使您将root过滤为无效的用户名,也可以伪装成任意用户,从而为滥用提供了大量机会。

[2] sudo甚至可以配置为允许它而不需要密码,但是这条路上有龙。如果你尝试的话,请确保你知道自己在做什么,以免你的用户自由地随意冒充对方。