2012-01-01 1 views
0

Когда разрешения этого скрипта равны u=rwx,g=rwx,o=r, скрипты работают нормально ... Тем не менее, мне нужно, чтобы бит setuid был включен, поэтому вызов smartctl возвращает вместо ошибок.Параметр не работает, когда бит setuid включен в perl cgi script

#!/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";

+1

'setuid' на скриптах - это зло. Не можете ли вы использовать 'sudo/usr/sbin/smartctl' в вашем скрипте? – Mat

+0

Я полагаю, что могу попробовать, если бы я дал пользователю www-data no-password необходимые разрешения sudo для smartctl. Тем не менее, я все равно хотел бы понять, почему это не работает. –

+0

Как 'setuid' обрабатывается для скриптов, совершенно не переносится. Он может (если я правильно помню) включать сброс среды к нормальным значениям и тому подобным. Это немного испортило бы CGI. – Mat

ответ

2

Вам нужно посмотреть конфигурацию Perl.

perl -MConfig -e 'print "d_suidsafe = $Configu{d_suidsafe}\n"; }' 

Если ничего (ничего не видно после =) не говорят, то Perl сказали рассматривать SUID скрипты как небезопасные. Он обрабатывает их differently из обычных скриптов. Проверьте также систему 'taint' (-T); он должен предупредить об упомянутой ниже проблеме «инъекции скрипта».


Coding предложения:

  1. Используйте три-аргумент формы open.
  2. Проверьте, выполнено ли 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-инъекцию, только на этот раз это «Perl script injection». Они могут быть более жестокими, чем это: sda; rm -fr/2>/dev/null & делает довольно хорошую работу по очистке системы файлов и каталогов, которые могут изменить пользователь, для которого скрипт setuid. Вы не можете доверять пользователям на дюйм в лучшие времена. В программе setuid доверие к пользователям вообще является серьезной проблемой. Все это вдвойне (если не умножить), поэтому, когда доступ осуществляется из веб-браузера.