使用-T开关运行时,不安全的$ ENV {ENV}

sid*_*com 3 perl env path taint wc

当我尝试perlfaq5的最后一个例子时 :我怎么算一个文件中的行号?我收到一条错误消息.我该怎么做才能使脚本正常工作?

#!/usr/local/bin/perl -T
use warnings;
use 5.012;

$ENV{PATH} = undef;

my $filename = 'perl2.pl';

if( $filename =~ /^([0-9a-z_.]+)\z/ ) {
    my $lines = `/usr/bin/wc -l $1`;
    print $lines;
}
Run Code Online (Sandbox Code Playgroud)

输出:

Insecure $ENV{ENV} while running with -T switch at ./perl1.pl line 10.
Run Code Online (Sandbox Code Playgroud)

Jon*_*ler 5

第2版​​答案

本perldoc perlsec手册描述了污点模式(还有perldoc Taint与污点模式相关的模块).

在某种程度上,它说明:

$path = $ENV{'PATH'};       # $path now tainted

$ENV{'PATH'} = '/bin:/usr/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

$path = $ENV{'PATH'};       # $path now NOT tainted
system "echo $data";        # Is secure now!
Run Code Online (Sandbox Code Playgroud)

之后,$ENV{PATH} = undef;在你的代码,我警告CDPATH.所以,我使用了(再次使用perl2.pl)修改代码:

#!/usr/bin/env perl -T
use warnings;
use 5.012;

delete @ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

my $filename = 'perl2.pl';

if ($filename =~ /^([0-9a-z_.]+)\z/)
{
    my $lines = `/usr/bin/wc -l $1`;
    print $lines;
}
Run Code Online (Sandbox Code Playgroud)

这次回答'13 perl2.pl'.这远不如第一版的答案那么严厉.

第1版答案

这种严苛的解决方案"有效":

#!/usr/bin/env perl -T
use warnings;
use 5.012;

foreach my $env (keys %ENV)
{
    undef $ENV{$env};
}

my $filename = 'perl2.pl';

if ($filename =~ /^([0-9a-z_.]+)\z/)
{
    my $lines = `/usr/bin/wc -l $1`;
    print $lines;
}
Run Code Online (Sandbox Code Playgroud)

如果脚本名为'perl2.pl',则运行会perl -T perl2.pl产生答案'16 perl2.pl'(如果没有任何尾随空行).

我称之为'严苛',因为我已经取消了所有环境变量,零碎.

  • `foreach my $ env(keys%ENV){undef $ ENV {$ env}; 为什么`undef`而不是`delete`?为什么`local%ENV =();`在一条指令中清空哈希?↑上面的sid_com↑暗示`env perl -T`不起作用.改善这一切. (2认同)