4

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

出于测试目的,我将我希望 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在脚本中指定 from。

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

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

4

1 回答 1

4

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

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

更改 uid 后,这段代码实际上应该做什么?也许有一种方法可以做到这一点而不必setuid

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

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

于 2011-02-14T10:47:08.257 回答