8

Perl 的Marpa解析器的文档包含以下有关污染数据的部分:

Marpa::R2 的存在是为了允许其输入以灵活而强大的方式改变执行。Marpa 不应与不受信任的输入一起使用。在 Perl 的污点模式下,将 Marpa 的 SLIF 接口与受污点的语法、受污点的输入字符串或受污点的标记值一起使用是一个致命错误。

我不确定,如果我了解此限制的后果。我明白,语法一定不能被污染。但我不明白输入一定不能被污染。对我来说,验证输入是解析器的任务。对我来说,解析器必须信任它的输入听起来不合理。

真的是这样吗?用 Marpa 实现任何一种公共网络服务是不可能的吗?

我问这个是因为其中一个参考用例是Marpa HTML 解析器,在我看来,使用 HTML 解析器是矛盾的,尽管大约 99.99% 的 HTML 可能被污染,但它不能用于受污染的数据。

任何人都可以解释这个矛盾吗?

4

2 回答 2

6

Marpa 实际上比其他解析器更安全,因为它解析的语言正是 BNF 指定的语言。使用正则表达式、PEG 等,很难确定实际解析的是哪种语言。在实践中,程序员倾向于让一些测试用例工作,然后放弃。

特别是,对不需要的输入的解析可能是一个主要的安全问题——使用传统的解析器,您通常不知道您让通过的所有内容。很少有测试套件检查是否确实接受了应该是错误的输入。Marpa准确地解析了规范中的语言——不多也不少。

那么为什么要使用关于污点模式的可怕语言呢?在最普遍的情况下,Marpa 可以被视为一种编程语言,并且具有完全相同的安全问题。允许用户执行任意代码在定义上是不安全的,而这正是 C、Perl、Marpa 等设计的。您不能为不受信任的用户提供通用语言界面。这对于 C、Python 等来说是很清楚的,但我认为在 Marpa 的情况下有人可能会忽略它。因此,恐吓语言。

恕我直言,Marpa 比竞争技术更安全。但是,在最一般的情况下,这还不够安全。

于 2015-11-10T13:56:08.120 回答
1

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

典型的例子是代码注入漏洞: 妈妈的功劳

这就是“污点模式”所做的一切——它强制在以危险的方式使用不受信任的输入之前运行清理。

去污很简单——您需要做的就是对源数据应用正则表达式过滤器,以便排除任何“危险”元字符。(应该注意 -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 会绕过验证。

在您的具体情况下:

  • 污点模式是可选的。当您收到不受信任的输入(例如来自潜在恶意用户)时,您应该使用它,但它可能比您自己使用更麻烦。

  • 过滤 HTML 以验证长度和字符集可能是明智的。例如 - 检查它是“ascii compatible character encoding”

从根本上说,尽管我认为您过度考虑了污染检查是什么——它不是一种详尽的验证方法——它是一个安全网。它所做的只是确保您在将用户输入传递给不安全的机制之前完成了一些基本的清理工作。这是为了阻止像我概述的那样荒谬的陷阱——其中大部分都可以通过一个简单的正则表达式来捕获。

如果您意识到这个问题,并且不担心恶意用户输入,那么我认为您无需过度担心。一个字符白名单就足够了,然后解析掉。

于 2015-11-10T13:05:01.610 回答