代码之家  ›  专栏  ›  技术社区  ›  MiffTheFox

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

  •  9
  • MiffTheFox  · 技术社区  · 16 年前

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

    HTML Purifier 通过解析CSS,根据白名单运行解析后的CSS,然后基于解析后的白名单CSS输出新的样式表。

    外面已经有这样的图书馆了吗?如果没有,是否有可用于创建自定义实现的CSS解析库?

    1 回复  |  直到 16 年前
        1
  •  4
  •   Ionuț G. Stan    16 年前

    我猜你会写你自己的CSS解析器和过滤器,所以这里我会考虑,虽然我从来没有做过这样的事情:

    • color , font-family .
    • background background-color , background-image .
    • 在解析过程中要非常严格,丢弃解析器不理解的所有内容,即使它是有效的CSS。换句话说,创建自己的CSS子集。

    解析时,最困难的部分是对 complex CSS selectors . 但是你也可以在这里强加你自己的子集。

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

    <?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;
        }
    }
    
    推荐文章