2015-11-15 3 views
3

Некоторые встроенные функции, такие как system и exec (а также backticks) будут использовать оболочку (по-моему, sh), если передано один аргумент, содержащий метасимволы оболочки. Если я хочу написать переносную программу, которая позволяет избежать каких-либо предположений о базовой оболочке, есть ли прагма или какой-либо другой параметр, который я могу использовать для отключения доступа к оболочке или для запуска фатальной ошибки немедленно?Perl отключить доступ к оболочке

+0

Вы можете избежать оболочки в 'system' и' exec', используя синтаксис 'system PROGRAM LIST', см. Документацию для [system] (http://perldoc.perl.org/functions/system.html) –

ответ

4

Об этом подробно пишут в Mastering Perl. Короткий ответ заключается в использовании system в виде списка.

system '/path/to/command', @args; 

Это не интерпретировать специальные символы в @args.

В то же время, вы должны включить проверку taint, чтобы помочь поймать плохие данные, прежде чем передавать их в систему. Для получения дополнительной информации см. Документацию perlsec.

+1

Is есть способ обновить использование 'system' в не-list-форме до ошибки? –

0

Имеются ограниченные возможности для этого, имейте в виду, что это основные процедуры и полное отключение их может иметь некоторые неожиданные последствия. У вас есть несколько вариантов.

Override Локально

Вы можете переопределить систему и Exec локально с помощью subs прагму, это только эффект пакет, в который вы импортировали подпрограмму:

#!/usr/bin/env perl 

use subs 'system'; 
sub system { die('Do not use system calls!!'); } 
# .. more code here, note this will runn 
my $out = system('ls -lah'); # I will die at this point, but not before 
print $out; 

Override Глобально

Чтобы переопределить глобально, в текущем процессе perl, вам необходимо импортировать вашу функцию в C ORE :: GLOBAL псевдо-пространство имен во время компиляции:

#!/usr/bin/env perl 

BEGIN { 
    *CORE::GLOBAL::system = sub { 
     die('Do not use system calls.'); 
    }; 

    *CORE::GLOBAL::exec = sub { 
     die('Do not use exec.'); 
    }; 

    *CORE::GLOBAL::readpipe = sub { 
     die('Do not use back ticks.'); 
    }; 
} 

#... 
my $out = system('ls -lah'); # I will die at this point, but not before 
print $out; 

Предотвратить что-нибудь форма работает, если в источнике

Если вы хотите, чтобы предотвратить любой код работает, прежде чем попасть в систему вызова можно включить следующие , обратите внимание, что это довольно свободно в это согласование, я написал, что это будет легко изменить или обновить:

package Acme::Noshell; 

open 0 or print "Can't execute '$0'\n" and exit; 
my $source = join "", <0>; 

die("Found back ticks in '$0'") if($source =~ m/^.*[^#].*\`/g); 
die("Found 'exec' in '$0'") if($source =~/exec\W/g); 
die("Found 'system' in '$0'") if($source =~/system\W/g); 

1; 

который может быть использован следующим образом:

#!/usr/bin/env perl 
use strict; 
use warnings; 
use Acme::Noshell; 

print "I wont print because of the call below"; 
my $out = system('ls -lah'); 
Смежные вопросы