为什么在Perl的污点模式下管道是否打开?

时间:2009-06-08 11:17:52

标签: perl taint

我原来的脚本如下:

my $cmd = "dir";
open (H, "$cmd |");
my @result = <H>;
close (H);
print STDERR @result,"\n";

这个脚本运行正常。如果我在脚本中添加以下行,则无法正常工作:

$ENV{"LD_LIBRARY_PATH"} = "/opt/VRTSsfmh/lib";
$ENV{PATH}="/usr/bin:/bin:/sbin:/usr/sbin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

调用管道打开时Perl使用了什么?

添加以下代码解决了问题:

if ($^O =~ /Win32/i) 
{
    $ENV{'SystemRoot'} =~ /([A-Z]:(\\[A-Za-z0-9_]+)+)/;
    my $system32_dir = $1."\\system32";
    $ENV{'PATH'} = $system32_dir;
}

2 个答案:

答案 0 :(得分:7)

您的问题与污点模式无关。你设置

$ENV{PATH}="/usr/bin:/bin:/sbin:/usr/sbin";

这些目录通常不存在于Windows计算机上。 dir是一个cmd.exe内部命令,因此为了能够执行该命令,您需要将它所在的目录添加到路径中。

现在,请注意,您进行此操作的方式与设置已知确定位置的路径的整个点相矛盾。恶意用户肯定可以将此环境变量更改为指向其dir的危险版本。

如果您依赖任何shell内置函数,Windows不一定安装在C:\ Windows中这一事实会使在Windows上编写一个安全的脚本变得复杂。

编辑:这是一个简短的测试程序,您可以将其用作基线:

#!/usr/bin/perl -T

use strict;
use warnings;

$ENV{PATH} = join(';', qw(C:\Windows C:\Windows\System32) );
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

open my $pipe_h, '-|', 'dir'
    or die "Cannot open pipe to dir: $!";

print while <$pipe_h>;

close $pipe_h
    or die "Cannot close pipe to dir: $!";

__END__

C:\Temp> perl -T v.pl

...

2009/05/25  08:58 AM             3,584 zzz.exe
              64 File(s)     32,125,365 bytes
              14 Dir(s)  39,251,894,272 bytes free

基本上,您需要的是系统管理员在安装时硬编码可接受的路径,以及不受信任的用户不要对脚本具有写入权限。

答案 1 :(得分:0)

污点模式很复杂。你真的必须阅读并理解perldoc perlsec。您的问题已在Cleaning Up Your Path部分的第一句中解决。