当此脚本的权限为 u=rwx,g=rwx,o=r
时,脚本工作正常...但是,我需要打开 setuid 位以便调用到 smartctl 返回所需的数据而不是错误。
#!/usr/bin/perl
use strict;
use warnings;
use CGI qw(:standard);
my $device = param("device") || "sda";
print header("text/plain");
print "device = $device\n\n";
$ENV{"PATH"} = "/usr/sbin";
open( PS, "smartctl -A /dev/$device |" );
while( <PS> )
{
print $_ . "\n";
}
close( PS );
当我将权限设置为 u=rwxs,g=rwxs,o=r
时,脚本在查询未指定 device
时起作用。但是当 device
被指定时,在 print "device = $device\n\n";
最佳答案
你需要看看Perl的配置。
perl -MConfig -e 'print "d_suidsafe = $Configu{d_suidsafe}\n"; }'
如果它什么也没说(在 =
之后什么都看不到),那么 Perl 被告知将 SUID 脚本视为不安全的。它对待他们differently从常规脚本。检查'taint'系统(-T
命令行选项);它应该警告下面提到的“脚本注入(inject)”问题。
编码建议:
- 使用
open
的三参数形式。 - 检查
打开
是否成功。
像这样:
open my $PS, "-|", "smartctl -A /dev/$device"
or die "Could not popen smartctl: $!";
好吧,可能不是die
,而是干净利落地报错,不要使用未打开的文件句柄。
if (open my $PS, "-|", "smartctl -A /dev/$device")
{
while (<$PS>)
{
print "$_\n";
}
close $PS;
}
else
{
print "Failed to open device: $!";
}
请注意,您需要拒绝或清理以下人员的输入:sda; cp/bin/sh/tmp/...; chmod 6777/tmp/...
在设备参数字段中。这有点像 SQL 注入(inject),只不过这次是“Perl 脚本注入(inject)”。他们可能比那更残忍:sda; rm -fr/2>/dev/null &
在清理文件和目录系统方面做得相当好,脚本是 setuid 的用户可以修改这些文件和目录。即使在最好的时候,你也不能相信用户一寸。在 setuid 程序中,完全信任用户是一个严重的问题。当访问来自 Web 浏览器时,所有这些加倍(如果不是成倍增加的话)。
关于linux - 当 perl cgi 脚本中的 setuid 位打开时,param 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8695903/