以下代码中的变量$ 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具有相同的价值,但是没有得到评估
答案 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];