在 CGI
脚本中使用 Perl
和 taint mode 给出以下内容我无法通过以下内容。
tail /etc/httpd/logs/error_log /usr/local/share/perl5/Net/DNS/Dig.pm line 906 (#1) (F) You tried to do something that the tainting mechanism didn't like. The tainting mechanism is turned on when you're running setuid or setgid, or when you specify -T to turn it on explicitly. The tainting mechanism labels all data that's derived directly or indirectly from the user, who is considered to be unworthy of your trust. If any such data is used in a "dangerous" operation, you get this error. See perlsec for more information. [Mon Jan 6 16:24:21 2014] dig.cgi: Insecure dependency in eval while running with -T switch at /usr/local/share/perl5/Net/DNS/Dig.pm line 906.
Code:
#!/usr/bin/perl -wT
use warnings;
use strict;
use IO::Socket::INET;
use Net::DNS::Dig;
use CGI;
$ENV{"PATH"} = ""; # Latest attempted fix
my $q = CGI->new;
my $domain = $q->param('domain');
if ( $domain =~ /(^\w+)\.(\w+\.?\w+\.?\w+)$/ ) {
$domain = "$1\.$2";
}
else {
warn("TAINTED DATA SENT BY $ENV{'REMOTE_ADDR'}: $domain: $!");
$domain = ""; # successful match did not occur
}
my $dig = new Net::DNS::Dig(
Timeout => 15, # default
Class => 'IN', # default
PeerAddr => $domain,
PeerPort => 53, # default
Proto => 'UDP', # default
Recursion => 1, # default
);
my @result = $dig->for( $domain, 'NS' )->to_text->rdata();
@result = sort @result;
print @result;
我通常使用 Data::Validate::Domain检查“有效”域名,但无法以不会发生受污染变量错误的方式部署它。
我读到,为了清除变量,您必须通过带有捕获组的 regex
传递它,然后加入捕获组以对其进行清理。所以我部署了$domain =~/(^\w+)\.(\w+\.?\w+\.?\w+)$/
。如图here它不是最好的 regex
来清除域名和覆盖所有可能的域,但它满足了我的需要。不幸的是,我的脚本仍在产生受污染的故障,我不知道是怎么回事。
Regexp-Common不提供域 regex
并且模块似乎无法使用无污染变量,所以我现在不知所措。
如何让这个东西通过污点检查?
最佳答案
$domain
未被污染
我确认您的 $domain
没有被感染。在我看来,这是您使用的唯一可能被污染的变量。
perl -T <(cat <<'EOF'
use Scalar::Util qw(tainted);
sub p_t($) {
if (tainted $_[0]) {
print "Tainted\n";
} else {
print "Not tainted\n";
}
}
my $domain = shift;
p_t($domain);
if ($domain =~ /(^\w+)\.(\w+\.?\w+\.?\w+)$/) {
$domain = "$1\.$2";
} else {
warn("$domain\n");
$domain = "";
}
p_t($domain);
EOF
) abc.def
打印
Tainted
Not tainted
Net::DNS::Dig 的作用
参见 Net::DNS::Dig第 906 行。它是 to_text
方法的开始。
sub to_text {
my $self = shift;
my $d = Data::Dumper->new([$self],['tobj']);
$d->Purity(1)->Deepcopy(1)->Indent(1);
my $tobj;
eval $d->Dump; # line 906
…
从 new
定义我知道 $self
只是 hashref 包含来自 new
参数的值和构造函数中填充的其他几个值。 $d->Dump
生成的评估代码将 $tobj
设置为 $self
的深拷贝 (Deepcopy(1)
),具有正确设置的自引用(Purity(1)
)和基本的 pretty-print (Indent(1)
)。
问题出在哪里,如何调试
根据我对 &Net::DNS::Dig::to_text
的了解,很明显问题出在 $self
中至少有一个受污染的项目。因此,您有一种直接的方法来进一步调试您的问题:在您的脚本中构建 $dig
对象后,检查它的哪些项目被污染了。您可以使用 print Data::Dumper::Dump($dig);
将整个结构转储到标准输出,这与评估代码大致相同,并使用 &Scalar 检查可疑项: :Util::污染
。
我不知道这离使 Net::DNS::Dig
在污点模式下工作还有多远。我不使用它,我只是好奇,想找出问题所在。由于您设法以其他方式解决了您的问题,我将其保留在这个阶段,让其他人继续调试该问题。
关于regex - 为 CGI 输入域名的 Perl 污染模式导致 “Insecure dependency in eval”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20960650/