问题描述
我有一个 Perl 脚本,可以通过 Apache 或命令行调用.
I have a Perl script that is called either via Apache or on the command-line.
出于测试目的,我将希望 Perl 脚本使用的用户名传递给它,并使用 POSIX::setuid
设置 uid
.
For testing purposes, I pass it the username I want the Perl script to operate with, and use POSIX::setuid
to set the uid
.
如果我从命令行运行脚本,则 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 $<;
}
else {
print header(-status => 401);
print "Could not setuid to correct uid (currently: )".getuid()."\n";
}
命令行输出显示指定$username
的正确uid
,而不是开始运行的测试帐户的uid
脚本.
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.
如果我通过 Apache 调用脚本,那么 uid
将保持设置为 apache
用户的 id,并且永远不会改变.
If I call the script via Apache, then the uid
remains set to the id of the apache
user, and never changes.
我不相信我可以在这里使用 suExec
,因为在阅读文档后:
I don't believe I can use suExec
here, because, after reading the documentation:
我无法为每个
$username
将此脚本的副本放入http://www.example.com/~username
.脚本需要从一个位置运行,我需要从脚本中指定uid
.
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.
我需要在运行时以指定的用户名运行脚本,而不是在 Apache 配置文件的虚拟主机指令中指定一次的单个用户名.每次新用户运行此脚本时更改此配置文件并重新启动 Apache 是不现实的.
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.
在使用 setuid()
时,如何让 Perl 脚本作为 cgi-bin 运行以正确更改 uid
?
How do I get a Perl script running as a cgi-bin to change the uid
correctly, when using setuid()
?
推荐答案
您可以setuid
到任意 uid 的唯一方法是以 root 身份运行.[1]
The only way you can setuid
to an arbitrary uid is to run as root.[1]
我不了解你,但以 root 身份运行 CGI 程序的想法让我做噩梦.
I don't know about you, but the idea of a CGI program running as root gives me nightmares.
更改 uid 后,这段代码实际上应该做什么?也许有一种无需 setuid
即可完成此操作的方法?
What is this code supposed to actually do after changing uid? Perhaps there's a way to accomplish this without having to setuid
?
[1] 根据您的代码及其安全模型,您可能能够收集用户的密码并使用 su
/sudo
[2] 运行单独的在 Web 服务器环境之外运行实际操作的命令行程序,但是 su
/sudo
能够这样做,因为它们是 suid root 并且它仍然会打开解决与以 root 身份运行 CGI 代码相关的大部分/所有问题.即使您将 root 作为无效用户名过滤掉,如果能够伪装成任意用户,也会为滥用提供大量机会.
[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, but su
/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
甚至可以配置为允许它不需要密码,但是沿着这条路走下去.如果您尝试,请确保您知道自己在做什么,以免让您的用户随意模仿对方.
[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.
这篇关于用作 cgi-bin 时如何使用 setuid() 成功运行 Perl 脚本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!