如何在PHP中实现基于白名单的CSS过滤

如何在PHP中实现基于白名单的CSS过滤,php,css,validation,user-input,Php,Css,Validation,User Input,我在一个网站上工作,我想让一个用户能够进入自定义CSS,将公开显示 然而,鉴于大量XSS攻击可以通过CSS进行,我希望能够找到一种“清理”CSS输出的方法,类似于工作原理,通过解析CSS,根据白名单运行解析的CSS,然后基于解析和白名单CSS输出新的样式表 外面已经有这样的图书馆了吗?如果不是,有一个CSS解析库可以用来创建一个定制的实现吗?< p>我想你会编写自己的CSS解析器和过滤器,所以这里我会考虑,尽管我从来没有做过这样的事情: 制作一个用户可以使用的可接受CSS属性的(白色)列表。例

我在一个网站上工作,我想让一个用户能够进入自定义CSS,将公开显示

然而,鉴于大量XSS攻击可以通过CSS进行,我希望能够找到一种“清理”CSS输出的方法,类似于工作原理,通过解析CSS,根据白名单运行解析的CSS,然后基于解析和白名单CSS输出新的样式表


外面已经有这样的图书馆了吗?如果不是,有一个CSS解析库可以用来创建一个定制的实现吗?

< p>我想你会编写自己的CSS解析器和过滤器,所以这里我会考虑,尽管我从来没有做过这样的事情:

  • 制作一个用户可以使用的可接受CSS属性的(白色)列表。例如:
    颜色
    字体系列
  • 我认为至少在开始时,最好不要使用诸如
    background
    之类的速记形式,这样您就可以轻松地解析这些值。要求他们明确地书写背景色、背景图像
  • 如果您想要URL,只允许相对URL,并放弃所有看起来不像URL的内容。无论如何都要记录这些问题,以便改进解析器和验证器
  • 在解析过程中要非常严格,丢弃解析器不理解的所有内容,即使它是有效的CSS。换句话说,创建自己的CSS子集
解析时,最难的部分是对的解析。但是你也可以在这里强加你自己的子集

下面是一些(伪)代码,也许它会对您有所帮助:

<?php

function tokenizeCSS() {
    return array(
        array(
            'selector'   => '#foo .bar',
            'properties' => array(
                'background-color' => 'transparent',
                'color'            => '#fff',
            ),
        );
    );
}

function colorValidator($color)
{}

/**
 * This is basically the white list. Keys are accepted CSS properties
 * and values are the validator callbacks.
 */
$propertyValidators = array(
    'background-color' => 'colorValidator',
    'color'            => 'colorValidator',
);

$filteredRules = array();

foreach (tokenizeCSS() as $rule) {
    if (! validSelector($rule['selector'])) {
        continue;
    }

    foreach ($rule['properties'] as $property => $value) {
        /**
         * Check property is in white list
         */
        if (! isset($propertyValidators[$property]) {
            continue;
        }

        /**
         * Check property is valid
         */
        if (! $propertyValidators[$property]($value)) {
            continue;
        }

        /**
         * Valid rule
         */
        $filteredRules[$rule['selector']][$property] = $value;
    }
}

我不知道有任何这样的库,但是CSS解析器应该没有那么难实现。CSS解析并不像看上去那么容易,特别是当你不得不禁止某些可能被糟糕的浏览器解析器误解的构造时。黑名单肯定很难,但白名单却不是。我不知道解析CSS有什么困难。它不是一种编程语言,在这种特殊情况下,您不需要基于它呈现某些东西。有些CSS结构可能更难解析,它们是@规则,但您不必支持完整的CSS规范,只需支持白名单中的子集即可。