Regex 通过正则表达式进行Perl污染 短版
在下面的代码中,Regex 通过正则表达式进行Perl污染 短版,regex,perl,security,taint,Regex,Perl,Security,Taint,在下面的代码中,$1被污染了,我不明白为什么 长版本 我在一个启用了污染检查模式的PerlV5.14.2系统上运行。 通过调试该设置中的一个问题,我成功地构建了以下SSCCE。(请注意,我编辑了这篇文章,第一个版本更长、更复杂,评论中仍然提到这一点。) 尽管输入字符串$var未被污染,并且正则表达式是固定的,但生成的捕获组$1受到污染。我觉得很奇怪 对于污点和正则表达式,有这样的说法: 通过将值用作散列中的键,可以不受污染;否则 绕过污染机制的唯一方法是引用 正则表达式匹配的子模式。Perl假定
$1
被污染了,我不明白为什么
长版本
我在一个启用了污染检查模式的PerlV5.14.2系统上运行。
通过调试该设置中的一个问题,我成功地构建了以下SSCCE。(请注意,我编辑了这篇文章,第一个版本更长、更复杂,评论中仍然提到这一点。)
尽管输入字符串$var
未被污染,并且正则表达式是固定的,但生成的捕获组$1
受到污染。我觉得很奇怪
对于污点和正则表达式,有这样的说法:
通过将值用作散列中的键,可以不受污染;否则
绕过污染机制的唯一方法是引用
正则表达式匹配的子模式。Perl假定如果
您使用$1
,$2
等引用子字符串,您知道您要引用的内容
你写模式的时候我们在做什么
我可以想象,即使输入被污染了,输出也不会被污染。观察未受污染输入的反向污染输出,感觉就像perl中的一个奇怪的bug。但如果你多读一些perlsec,它也会指向用户。我们在那里读到:
当use locale生效时,Perl使用污染机制(请参阅
perlsec)标记与区域设置相关的字符串结果,以及
结果可能是不可信的。以下是本报告的摘要
可能受影响的运算符和函数的污染行为
区域设置:
- 比较运算符(
、lt
、le
、ge
和gt
)[…]cmp
- 案例映射插值(使用
,\l
,\l
或\u
)[…]\u
- 匹配运算符(
): 标量真/假结果从不受污染 子模式,作为列表上下文结果或作为m/
如果使用区域设置(但不是$1
)有效,并且子模式为常规模式 表达式包含使用区域设置),则会污染等 “:not_characters”
(用于匹配字母数字字符),\w
(非字母数字字符)、\w
(空白字符)或\s
(非空白字符)。匹配的模式变量,\s
,$&
(预匹配)、$`
(后匹配)和$”
(最后一次匹配)也都是 如果使用区域设置有效且正则表达式包含$+
,\w
,\w
或\s
\s
- 替换运算符(
)[…]s//
\w
、\w
、\s
或\s
,因此它不应该依赖于语言环境
有人能解释一下为什么这段代码污染了varibale
$1
?问题中引用的文档与perl 5.18.1的实际实现之间存在差异。问题是字符类。文档提到了\w
,\s
,\w
,\s
,在什么方面听起来像是一个详尽的列表,而几乎每次使用[…]
时,实现都会受到污染
正确的解决方案可能介于两者之间:像[[:word:]
这样的字符类应该受到污染,因为它取决于区域设置。我的固定列表不应该受到污染。像[a-z]这样的字符范围
取决于排序规则,因此我个人认为它们也应该被污染。\d
取决于区域设置对数字的看法,因此它也应该被污染,即使它既不是目前提到的转义序列,也不是括号中的类
因此,在我看来,文档和实现都需要修复。Perl开发人员正在处理这个问题。有关进度信息,请查看我提交的文档
对于一个固定的字符列表,一个可行的解决办法似乎是将其表述为析取,即
(?:\.\124;
而不是[.\u]
。它更为详细,但即使在当前(我认为有缺陷的)perl版本中也应该可以使用。我认为如果删除(奇怪的编写方式),它不会受到污染use locale;
?使用perlbug
工具将此信息发送到p5p
不会有什么坏处。如果不是文档中的错误,Perl中似乎存在错误。Scalar::Util qw(受污染)有什么问题
?@mpapec:Scalar::Util::tainted没有什么问题,它会产生相同的结果。我只是将Foswiki使用的代码粘贴在这里,因为它可能会减少代码的依赖性。我不知道是否每个人都有可用的Scalar::Util
,文档建议使用CPAN。Scalar::Util自5.8.0,十多年前。@ikegami:在
#!/usr/bin/perl -T
use strict;
use warnings;
use locale;
use Scalar::Util qw(tainted);
my $var = "foo.bar_baz";
$var =~ m/^(.*)[._](.*?)$/;
print(tainted($1) ? "tainted\n" : "untainted\n");