taint mode
是一个 perl 可选设置,表示 - 将用户输入视为不受信任。它会阻止您使用任何“受污染的”变量——例如直接从某些函数中读取STDIN
或ENV
在某些函数中读取的变量,因为这样做很危险。
典型的例子是代码注入漏洞:

这就是“污点模式”所做的一切——它强制在以危险的方式使用不受信任的输入之前运行清理。
去污很简单——您需要做的就是对源数据应用正则表达式过滤器,以便排除任何“危险”元字符。(应该注意 -perl
实际上并不知道什么是“危险的”,什么不是 - 它假设你不是一个白痴,只是“匹配”一切)
这将出错:
#!/usr/bin/env perl -T
use strict;
use warnings;
my $tainted = $ENV{'USERNAME'};
system ( "echo $tainted" );
因为我将一个不受信任的变量传递给“系统”,它可能具有嵌入式代码注入。
使用 -T 开关运行时系统中的不安全依赖性
(它也可能抱怨不安全的路径)
所以为了不被污染,我需要消毒。合理的清理方法是 - 用户名只能是字母数字:
#!/usr/bin/env perl -T
use strict;
use warnings;
$ENV{'PATH'} = '/bin'; # an untainted value
my $tainted = $ENV{'USERNAME'};
my ( $untainted ) = $tainted =~ m/(\w+)/g;
system ( "echo $untainted"); # no error now
而且因为我使用了正则表达式 - perl 假设我没有做一些愚蠢(.*)
的事情(比如 ),因此认为数据没有受到污染。
为什么这很重要?嗯,这取决于你的解析器做什么。解析器(就其本质而言)被无效输入“破坏”的情况并不少见。例如,请参见上面的内容 - 转义一些内联 SQL 会绕过验证。
在您的具体情况下:
从根本上说,尽管我认为您过度考虑了污染检查是什么——它不是一种详尽的验证方法——它是一个安全网。它所做的只是确保您在将用户输入传递给不安全的机制之前完成了一些基本的清理工作。这是为了阻止像我概述的那样荒谬的陷阱——其中大部分都可以通过一个简单的正则表达式来捕获。
如果您意识到这个问题,并且不担心恶意用户输入,那么我认为您无需过度担心。一个字符白名单就足够了,然后解析掉。