当用作 cgi-bin 时,如何使用 setuid() 成功运行 Perl 脚本?
我有一个 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";
}
命令行输出显示指定 $username
的正确 uid
code>,而不是开始运行脚本的测试帐户的 uid
。
如果我通过 Apache 调用脚本,则 uid
仍设置为 apache
用户的 id,并且永远不会更改。
我不相信我可以在这里使用 suExec
,因为在阅读文档后:
我无法将此脚本的副本放入
http://www.example 中。 com/~username
对于每个$username
。该脚本需要从一个位置运行,并且我需要在脚本中指定uid
。我需要让脚本在运行时作为指定的用户名运行,而不是作为 Apache 配置文件中的虚拟主机指令中指定的单个用户名运行。每次新用户运行此脚本时更改此配置文件并重新启动 Apache 是不现实的。
使用 setuid()
时,如何让 Perl 脚本作为 cgi-bin 运行以正确更改 uid
?
I have a Perl script that is called either via Apache or on the command-line.
For testing purposes, I pass it the username I want the Perl script to operate with, and use POSIX::setuid
to set the uid
.
If I run the script from the command line, then the uid
is set properly:
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 lt;;
}
else {
print header(-status => 401);
print "Could not setuid to correct uid (currently: )".getuid()."\n";
}
The command-line output shows the correct uid
of the specified $username
, instead of the uid
of the test account that started running the script.
If I call the script via Apache, then the uid
remains set to the id of the apache
user, and never changes.
I don't believe I can use suExec
here, because, after reading the documentation:
I can't put a copy of this script into
http://www.example.com/~username
for every$username
. The script needs to run from one location, and I need to specify theuid
from within the script.I need to have the script run as the specified username at runtime, and not as a single username specified once in a virtual host directive in an Apache configuration file. Changing this configuration file and restarting Apache every time a new user runs this script is not realistic.
How do I get a Perl script running as a cgi-bin to change the uid
correctly, when using setuid()
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
setuid
为任意 uid 的唯一方法是以 root 身份运行。[1]我不知道你怎么想,但以 root 身份运行 CGI 程序的想法让我做噩梦。
更改 uid 后这段代码实际上应该做什么?也许有一种方法可以实现这一点,而无需
setuid
?[1] 根据您的代码及其安全模型,您也许能够收集用户的密码并使用
su
/sudo
[2] 运行单独的命令行程序在 Web 服务器环境之外运行实际操作,但是su
/sudo
能够做到这一点,因为它们是 suid root 并且它仍然会打开大多数/无论如何,所有与以 root 身份运行 CGI 代码相关的问题。即使您将 root 作为无效用户名过滤掉,伪装成任意用户也会带来大量滥用机会。[2] sudo 甚至可以配置为允许它而不需要密码,但这条路上有龙。如果您尝试这样做,请确保您知道自己在做什么,以免您的用户可以随意冒充对方。
The only way you can
setuid
to an arbitrary uid is to run as root.[1]I don't know about you, but the idea of a CGI program running as root gives me nightmares.
What is this code supposed to actually do after changing uid? Perhaps there's a way to accomplish this without having to
setuid
?[1] Depending on your code and its security model, you may be able to collect the user's password and use
su
/sudo
[2] to run a separate command-line program to run the actual operations outside of the web server environment, butsu
/sudo
are able to do this because they're suid root and it would still open up most/all of the issues associated with running CGI code as root anyhow. Even if you filter out root as an invalid username, being able to masquerade as any arbitrary user opens up plenty of opportunities for abuse.[2]
sudo
could even be configured to allow it without requiring a password, but there be dragons down that path. Be sure you know what you're doing if you attempt it, lest you give your users free reign to impersonate each other at will.