提问人:Vyacheslav 提问时间:6/18/2023 更新时间:6/18/2023 访问量:22
如何在 HtmlPurufier 中允许 var(--...)
How to allow var(--...) in HtmlPurufier
问:
如何使用 HtmlPurifier 解析样式属性?
我尝试了这个配置:var(--...)
<?php
return [
'encoding' => 'UTF-8',
'finalize' => true,
'ignoreNonStrings' => false,
'cachePath' => storage_path('app/purifier'),
'cacheFileMode' => 0755,
'settings' => [
'default' => [
'HTML.Doctype' => 'HTML 4.01 Transitional',
'HTML.Allowed' => 'div,b,strong,i,em,s,u,a[class|href|title],ul,ol,li,p[style],br,span[style],img[width|height|alt|src]',
'CSS.AllowedProperties' => 'font,font-size,font-weight,font-style,font-family,text-decoration,padding-left,color,var,background-color,text-align',
'AutoFormat.AutoParagraph' => true,
'AutoFormat.RemoveEmpty' => true,
],
],
];
$string = '<span style="color: var(--myvar);">text</span>';
$string = Purifier::clean($string);
echo $string;
但是我得到了没有样式属性的结果:
<span>text</span>
预期结果:
<span style="color: var(--myvar);">text</span>
任何想法,谢谢!
答:
为什么会这样?
从根本上说,HTML Purifier 的工作原理是了解 HTML 和 CSS 的功能以及浏览器如何解释。它不仅允许您将标签或 CSS 列入白名单,而且还具有定义最大图像大小的旋钮,以防止 imagecrash 攻击并阻止将不受支持的子元素放入特定位置的尝试(例如 into without a ),它可能具有未定义的行为,在任何一个浏览器中都可能成为实际的漏洞。<div>
<ul>
<li>
为了能够执行这些操作,它需要了解您尝试列入白名单的所有元素。它带有广泛的开箱即用的 CSS 和 HTML 定义,但 (1) 即使在编写时,HTML Purifier 也有意不费心实现作者认为本质上不安全的 HTML 和 CSS 某些部分的知识,(2) HTML5 自 HTML Purifier 编写以来就已经发生,并且 CSS 已经取得了进步。
因此,您绝对有可能有一些良性输入,即使 HTML Purifier 被列入白名单,它也不会允许,因为它不理解输入。
你能做什么。
但!你可以教它。可悲的是,我刚才链接的 Customize! 文档是针对 HTML 元素的,而不是针对 CSS,但它引入了一些概念,这些概念对于理解 HTML Purifier 在后台的工作原理很有价值。我不会将它们粘贴到这里,因为它们与您的问题正交。
CSS目前没有一个很好的对应文档。HTML Purifier 论坛(archive.org 链接)上的添加新 css 属性
线程提供了有关如何执行此操作的一些信息。这是 Oliver Schonrock 发布的一个示例,它添加了一个 CSS 属性(而不是值),尽管如此,它可能会让你走上正确的轨道:
谢谢你的这篇文章。它帮助我完全按照 OP 的要求做了。下面是一个具体的代码示例,可以节省其他人的时间:
$config = HTMLPurifier_Config::createDefault(); // add some custom CSS3 properties $css_definition = $config->getDefinition('CSS'); $border_radius = $info['border-top-left-radius'] = $info['border-top-right-radius'] = $info['border-bottom-left-radius'] = $info['border-bottom-right-radius'] = new HTMLPurifier_AttrDef_CSS_Composite(array( new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Percentage(true) )); $info['border-radius'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_radius); // wrap all new attr-defs with decorator that handles !important $allow_important = $config->get('CSS.AllowImportant'); foreach ($info as $k => $v) { $css_definition->info[$k] = new HTMLPurifier_AttrDef_CSS_ImportantDecorator($v, $allow_important); } $html_purifier = new HTMLPurifier($config);
在您的示例中,您将需要编写一个自定义装饰器(类似于您在此示例代码中看到的装饰器),并将其分配给要支持的所有 CSS 属性。AttrDef
HTMLPurifier_AttrDef_CSS_ImportantDecorator
var()
但是,您可能不想这样做。如果你想正确地添加它,这可能很困难 - 例如,你需要确保没有人可以使用 s 来绕过 HTML Purifier 正在执行的值检查!(例如,有人可能能够以这种方式绕过 ImageCrash 防御,就像一个突出的例子)。var()
评论