regex - 为 CGI 输入域名的 Perl 污染模式导致 “Insecure dependency in eval”

标签 regex perl cgi

CGI 脚本中使用 Perltaint 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/

相关文章:

Python CGI 将正确的文本返回给curl,但浏览器显示尾随零

python - ajax 请求 python 脚本

python - 运行 python cgi 脚本解释器结果因浏览器而异

javascript - 如何使用javascript将内容中的url转换为链接

regex - perl 不区分大小写的开关作为变量?

ruby - 如何编写匹配包含数字的 URL 的模式?

linux - 如何在 Perl 脚本中调用函数(在 shell 脚本中定义)

perl - Perl:使用<>构造时如何获取文件名?

c# - 删除字符串中除 "ñ"以外的重音符号

regex - 在 Perl 中的变量中用反斜杠替换文本