HTML Purifier:禁用语法修复

时间:2018-01-21 16:14:17

标签: html sanitization htmlpurifier

考虑以下HTML Purifier设置:

require_once 'library/HTMLPurifier.auto.php';

$config = HTMLPurifier_Config::createDefault();
$config->set('Core.EscapeInvalidTags', true);
$purifier = new HTMLPurifier($config);
$clean_html = $purifier->purify($dirty_html);

如果您运行以下案例:

$dirty_html = "<p>lorem <script>ipsum</script></p>";

//output
<p>lorem &lt;script&gt;ipsum&lt;/script&gt;</p>

正如预期的那样,它不是删除无效标签,而是将它们全部转义。

但是,请考虑以下其他测试用例:

案例1

$dirty_html = "<p>lorem <b>ipsum</p>";

//output
<p>lorem <b>ipsum</b></p>

//desired output
<p>lorem &lt;b&gt;ipsum</p>

案例2

$dirty_html = "<p>lorem ipsum</b></p>";

//output
<p>lorem ipsum</p>

//desired output
<p>lorem ipsum&lt;/b&gt;</p>

案例3

$dirty_html = "<p>lorem ipsum<script></script></p>";

//output
<p>lorem ipsum&lt;script /&gt;</p>

//desired output
<p>lorem ipsum&lt;script&gt;&lt;/script&gt;</p>

不是仅仅转义无效标签,而是先修复它们然后将其转义。这样事情会变得非常奇怪,例如:

案例4

$dirty_html = "<p><a href='...'><div>Text</div></a></p>";

//output
<p><a href="..."></a></p><div><a href="...">Text</a></div><a href="..."></a>&lt;/p&gt;

问题
因此,是否可以禁用语法修复并只是转义无效标记?

1 个答案:

答案 0 :(得分:1)

您看到语法修复的原因是HTML Purifier接近HTML卫生主题的基本方式:首先解析HTML以理解它,然后决定哪一个要保留在已解析表示中的元素,然后呈现HTML。

您可能熟悉stackoverflow的一个most famous answers,这是一个有趣和恼怒的观察,真正的正则表达式无法解析HTML - 您需要额外的逻辑,因为HTML是一个上下文 - 免费语言,而不是常规语言。 (现代&#39;常规表达式不是正式的正则表达式,但这是另一回事。)换句话说,如果你真的想知道你的HTML中发生了什么 - 那么你正确地应用你的白名单或黑名单 - 你需要解析它,这意味着文本最终会以完全不同的方式呈现。

解析如何导致输入和输出之间发生变化的一个示例是HTML Purifier strips extraneous whitespace from between attributes,在您的情况下可能不会打扰您,但仍然源于HTML的解析表示与文本表示完全不同。它没有试图保留您输入的形式 - 它试图保留该功能。

当没有明确的功能并且必须开始猜测时,这会变得棘手。要选择一个示例,想象一下,在浏览HTML输入时,您会发现在不知名的地方看起来像一个开放的<td>标记 - 如果有一个未公开的<td>,您可以consider it valid只要你添加一个结束标记,就会标记一段时间,但如果你将第一个标记转义为&lt;td&gt;,那么你会need to discard the text data that would have been in the <td> - 因为 - 取决于浏览器呈现 - 它可能会将数据放入部分页面外部的视觉页面,即用户未明确提交的地点。

简而言之:您无法轻松删除所有语法修复和/或整理,而无需翻阅HTML Purifier的解析内容,并确保您找不到有价值的信息丢失。< / p>

那就是说,你可以尝试切换the underlying parsing engine with Core.LexerImpl ,看看它是否能让你获得更好的结果! :) DOMLex definitely adds missing ending nodes从一开始,但从粗略的一瞥,DirectLex可能不会。 HTMLPurifier's MakeWellFormed strategy class中存在大量自动关闭逻辑,这也可能对您造成问题。

根据为什么,您希望保留此数据(以便进行分析?),单独保存原始输入(同时保留HTML Purifier本身)可以为您提供更好的解决方案。< / p>