如何在 HtmlPurufier 中允许 var(--...)

How to allow var(--...) in HtmlPurufier

提问人:Vyacheslav 提问时间:6/18/2023 更新时间:6/18/2023 访问量:22

问:

如何使用 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>

任何想法,谢谢!

php htmlpurifier

评论


答:

0赞 pinkgothic 6/18/2023 #1

为什么会这样?

从根本上说,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 属性。AttrDefHTMLPurifier_AttrDef_CSS_ImportantDecoratorvar()

但是,您可能不想这样做。如果你想正确地添加它,这可能很困难 - 例如,你需要确保没有人可以使用 s 来绕过 HTML Purifier 正在执行的值检查!(例如,有人可能能够以这种方式绕过 ImageCrash 防御,就像一个突出的例子)。var()