Perl Marpa解析器的文档包含以下关于tainted data的部分:
Marpa :: R2的存在允许其输入以灵活和强大的方式改变执行。 Marpa不应该与不受信任的输入一起使用。在Perl'在污点模式下,使用带有污染语法,污染输入字符串或污染标记值的Marpa SLIF界面是一个致命错误。
我不确定,如果我理解这种限制的后果。我明白,语法一定不会被污染。但我不明白输入不应该被污染。对我来说,解析器的任务是验证输入。解析器必须信任其输入对我来说听起来不合理。
真的那样吗?用Marpa实现任何类型的公共网络服务是不可能的吗?
我问这个是因为其中一个参考用例是Marpa HTML parser,而且使用HTML解析器似乎是矛盾的,虽然大约99,99%的HTML都不能用于HTML可能会被污染。
有人可以解释这个矛盾吗?
答案 0 :(得分:6)
Marpa实际上比其他解析器更安全,因为它解析的语言正是BNF指定的语言。使用正则表达式,PEG等,很难确定实际解析的语言。在实践中,程序员倾向于让一些测试用例工作然后放弃。
特别是,解析不需要的输入可能是一个主要的安全问题 - 对于传统的解析器,您通常不会知道您要通过的所有内容。测试套件很少检查是否确实接受了应该是错误的输入。 Marpa在其规范中完全解析 语言 - 没有更多,仅此而已。
那为什么关于污点模式的恐怖语言呢?在最常见的情况下,Marpa可以被视为一种编程语言,并且具有完全相同的安全性问题。根据定义,允许用户执行任意代码是不安全的,而C,Perl,Marpa等正是设计。您不能为不受信任的用户提供通用语言界面。这对C,Python等来说很明显,但我认为有人可能会在Marpa的情况下忽略它。因此恐吓语言。
Marpa比竞争技术更安全。但是,在最一般的情况下,这不够安全。
答案 1 :(得分:1)
taint mode
是一个perl可选设置,表示 - 将用户输入视为不可信。它会阻止你使用任何" tainted"变量 - 例如在某些函数中从STDIN
或ENV
直接读取的那些变量,因为这样做很危险。
所有"污点模式"确实 - 在以不安全的方式使用不受信任的输入之前,它强制执行运行清理。
untainting is straightforward - 您所需要做的就是对源数据应用正则表达式过滤器,这样任何“危险的”过滤器都可以使用。元字符被排除在外。 (应该注意 - perl
实际上并不知道什么是“危险的”和“不是什么” - 它假设你不是一个白痴而只是& #39;匹配'一切)
这将是错误:
#!/usr/bin/env perl -T
use strict;
use warnings;
my $tainted = $ENV{'USERNAME'};
system ( "echo $tainted" );
因为我将不受信任的变量传递给" system"并且可能嵌入了代码注入。
使用-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假设我没有做过任何愚蠢的事情(比如(.*)
),因此认为数据不受污染。
为什么这很重要?嗯,这取决于你的解析器做什么。对于解析器而言,这种情况并不罕见 - 就其性质而言 - 被破坏了#39;通过无效输入。例如,请参阅上面的内容 - 转义某些内联SQL会绕过验证。
在您的具体案例中:
污染模式是可选的。当您收到不受信任的输入时(<例如来自潜在的恶意用户), 应使用它,但它可能比您自己使用它的价值更麻烦。
过滤HTML以验证长度和字符集可能是明智的。例如 - 检查它是"ascii compatible character encoding"。
从根本上说,虽然我认为你过度思考污染检查是什么 - 它不是一种详尽的验证方法 - 它是一个安全网。它所做的只是确保您在将用户输入传递给不安全的机制之前已经完成了某些基本的清理工作。这样可以阻止像我概述的那些荒谬的陷阱 - 其中大部分可以被一个简单的正则表达式捕获。
如果您已发现问题,并且不关心恶意用户输入,那么我认为您不必过于担心。角色白名单就足够了,然后解析掉。