perl eval()在字符串变量上给出'在使用-T开关运行时的eval中的不安全依赖性'

时间:2014-05-12 14:59:37

标签: perl

以下代码中的变量$ var和$ var2保持相同的值,但在eval()方面表现不同。

来源:

use Data::Dumper; 

sub trim($)
{
    my $string = shift;
    $string =~ s/^\s+//;    
    $string =~ s/\s+$//;
    $string =~ s/\R//g;
    return $string;
}

my $var2="";
$var2.="{id=>1962}";
$var2.=",{id=>1645}";
$var2.=",{id=>905}";
$var2.=",{id=>273}";
$var2.=",{id=>1800}";
$var2.=",{id=>21}";
$var2.=",{id=>1639}";
$var2.=",{id=>55}";
$var2.=",{id=>57}";
$var2.=",{id=>59}";
$var2.=",{id=>420}";
$var2.=",{id=>418}";
$var2="[".$var2."]";

print Dumper $var2;
print Dumper eval($var2); #evaluates to an ARRAY

my $filename = "sample.txt";
open(FILE, $filename) or die "Can't read file 'filename' [$!]\n";  
$document = <FILE>; 
close (FILE);  
$document=trim($document);
@data = split(',', $document);     
my $var = "";
foreach my $val (@data) {
     $var.="{id=>".$val."},";               
}         
chop($var);
$var =  "[".$var."]";
print "\n";

if ($var eq $var2){
    print "var and var2 stringwise equal\n" ;
}else{
    print "var and var2 stringwise not equal\n" ;
}

print Dumper $var;
print Dumper eval($var); #error

exit(0);

sample.txt的内容:

1962,1645,905,273,1800,21,1639,55,57,59,420,418

输出:

$VAR1 = '[{id=>1962},{id=>1645},{id=>905},{id=>273},{id=>1800},{id=>21},{id=>1639},{id=>55},{id=>57},{id=>59},{id=>420},{id=>418}]';
$VAR1 = [
          {
            'id' => 1962
          },
          {
            'id' => 1645
          },
          {
            'id' => 905
          },
          {
            'id' => 273
          },
          {
            'id' => 1800
          },
          {
            'id' => 21
          },
          {
            'id' => 1639
          },
          {
            'id' => 55
          },
          {
            'id' => 57
          },
          {
            'id' => 59
          },
          {
            'id' => 420
          },
          {
            'id' => 418
          }
        ];

var and var2 stringwise equal
$VAR1 = '[{id=>1962},{id=>1645},{id=>905},{id=>273},{id=>1800},{id=>21},{id=>1639},{id=>55},{id=>57},{id=>59},{id=>420},{id=>418}]';
Insecure dependency in eval while running with -T switch at assignment.pl line 51.

任何人都可以说出为什么&#34; eval($ var)&#34;尽管与$ var2具有相同的价值,但是没有得到评估

2 个答案:

答案 0 :(得分:2)

虽然$var可能与您在特定数据情况下的$var2相同,但并不总是如此。您的脚本也不会禁止eval,即使它不相同。

因此,受污染的检查是正确的抱怨不安全的eval,因为它旨在检测您的eval($var)肯定是不安全的操作。

通常,您应尽量避免使用eval,因为它是远程执行代码漏洞的主要来源。相反,您应该尝试使用其他更安全的方法解析数据结构,例如:在输入数据上使用split,然后循环生成的数组以生成所需的数据结构。

答案 1 :(得分:1)

这是perl Taint Mode完全正在做的事情。您正在读取外部资源中的数据,并且perl -T不允许您通过eval运行受污染的数据,因为这可能最终会做任何事情(非常不安全)。

为了launder your data,您只需要通过正则表达式来验证它是什么。替换以下行:

#my @data = split(',', $document);     
my @data = $document =~ m/(\d+)/g;

由于我们通过正则表达式运行外部文档数据,因此@data中的值将不再是tainted,而且可以是eval d。

无论哪种方式,我都建议不要使用eval,除非有特殊原因需要它。以下内容完成相同的操作而无需eval

my $var = [map {id => $_}, @data];