2011-02-14 76 views
3

我有一个通过Apache或命令行调用的Perl脚本。如何使用setuid()作为cgi-bin成功运行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"; 
} 

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

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

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

  1. 我不能把这个脚本的副本到http://www.example.com/~username每一个$username。脚本需要从一个位置运行,我需要在脚本中指定uid

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

我如何获得一个Perl脚本运行的cgi-bin目录正确地改变uid,用setuid()什么时候?

+1

您的命令行用户可能有权更改其UID,您的web服务器用户可能不会? – Konerak 2011-02-14 10:26:12

回答

4

您可以将setuid转换为任意uid的唯一方法是以root用户身份运行[1]。

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

此代码应该在更改uid后实际执行的是什么?也许有办法做到这一点,而不必setuid

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

[2] sudo甚至可以配置为允许它不需要密码,但是会有龙下来的路径。确保你知道自己在做什么,以免让用户随意冒充对方冒充对方。

+0

这个cgi-bin与Ajax调用一起使用。该脚本应该以指定的用户身份运行,以限制该用户访问其Web服务器可访问的文件系统上的文件列表。 – 2011-02-14 11:02:04