默认情况下,HTML Purifier 仅识别在某个范围内有效的标签<body>
上下文,因为这是它的预期用例。基本上,它实际上并不知道什么是<meta>
, <html>
, <head>
or <title>
标签是 - 这是一个大问题,因为它的大部分安全性依赖于理解 HTML 的语义基础!
关于这个主题有一些较旧的 stackoverflow 问题:
- HTMLPurifier,检查整个 HTML 文档 https://stackoverflow.com/q/1509268/245790
- 允许在 HTMLPurifier 中解析完整的 html https://stackoverflow.com/q/24037016/245790
...但他们目前没有非常有用的答案,所以经过一番思考,我认为你的问题仍然有其价值,我将在这里回答。
一般来说,这已经在 HTML Purifier 论坛上讨论过几次了(例如在允许 HTML、HEAD、STYLE 和 BODY 标记 http://htmlpurifier.org/phorum/read.php?3,6909,6909) - 但简而言之,如果没有大量的工作,您就无法做到这一点,不幸的是,我目前不熟悉任何通过简单的复制和粘贴来解决此问题的代码片段。
因此,您必须深入研究 HTML Purifier 的内部结构。
您可以使用以下方法教授 HTML Purifier 大多数标签和相关行为上的说明定制!文档页 http://htmlpurifier.org/docs/enduser-customize.html。对您来说最有趣的部分是靠近底部的部分,例如<form>
被教导 HTML Purifier。为后人引用那里的内容:
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.DefinitionID', 'enduser-customize.html tutorial');
$config->set('HTML.DefinitionRev', 1);
$config->set('Cache.DefinitionImpl', null); // remove this later!
$def = $config->getHTMLDefinition(true);
$def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(
array('_blank','_self','_target','_top')
));
$form = $def->addElement(
'form', // name
'Block', // content set
'Flow', // allowed children
'Common', // attribute collection
array( // attributes
'action*' => 'URI',
'method' => 'Enum#get|post',
'name' => 'ID'
)
);
$form->excludes = array('form' => true);
每个参数都对应于我们提出的问题之一。
请注意,我们在操作属性的末尾添加了一个星号
表明这是必需的。如果有人指定了没有该形式的表格
属性,该标签将被砍掉。另外,末尾的额外行是
防止表单嵌套的特殊额外声明
彼此。
您必须对 之外的所有标签执行类似的操作<body>
您想要支持的标签(一直到<html>
).
注意:即使您将所有这些标签添加到 HTML Purifier,设置Core.ConvertDocumentToFragment
您发现需要设置为false
(正如你所做的那样)。
选择
如果这看起来工作量太大,而您有其他消毒方法 http://htmlpurifier.org/comparison文档的标题部分和正文属性,您还可以将文档切成碎片,分别清理碎片,然后小心地将它们粘在一起。
(或者,当然,只需对整个文档使用替代方案。)