linux - 当 perl cgi 脚本中的 setuid 位打开时,param 不起作用

标签 linux perl apache cgi param

当此脚本的权限为 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)”问题。


编码建议:

  1. 使用open 的三参数形式。
  2. 检查打开是否成功。

像这样:

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/

相关文章:

ruby - Apache 与 Ruby - Gems 问题

linux - Linux shell 脚本中 10 个数字的最大值和最小值

perl - 当我将 Perl 代码放入 foreach 循环中时,为什么它不起作用?

arrays - 需要根据单独数组的排序对4个不同的数组进行排序

apache - 无法在 Centos 7 上启动 httpd 服务 "GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: Cannot determine user of subject"

node.js - 带有 apache 的 Socket.io - 套接字客户端 1 id 在连接客户端 2 时刷新

linux - 在 CentOS 上安装 phpmyadmin 时出错

两个IP的比较

linux - 比较shell中的两个变量

regex - Perl,删除前三个字符后的所有内容