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

Avi*_*ash 1 perl taint

我原来的脚本如下:

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

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

$ENV{"LD_LIBRARY_PATH"} = "/opt/VRTSsfmh/lib";
$ENV{PATH}="/usr/bin:/bin:/sbin:/usr/sbin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
Run Code Online (Sandbox Code Playgroud)

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

添加以下代码修复了该问题:

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

Sin*_*nür 7

您的问题与污点模式无关.你设定

$ENV{PATH}="/usr/bin:/bin:/sbin:/usr/sbin";
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

#!/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
Run Code Online (Sandbox Code Playgroud)

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