我原来的脚本如下:
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;
}
答案 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部分的第一句中解决。