如何在PHP中预先形成基于白名单的CSS过滤

Mif*_*Fox 9 css php validation user-input

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

然而,看到大量的XSS攻击可以通过CSS进行,我希望能够找到一种方法来"清理"CSS输出,类似于HTML Purifier的工作方式,通过解析CSS,运行解析的CSS针对白名单,然后根据已解析和列入白名单的CSS输出新的样式表.

那里有像这样的图书馆吗?如果没有,是否有可用于创建自定义实现的CSS解析库?

Ion*_*tan 4

我猜你会编写自己的 CSS 解析器和过滤器,所以这就是我会考虑的,尽管我从未做过这样的事情:

  • 制定用户可以使用的可接受 CSS 属性的(白)列表。喜欢:colorfont-family
  • 我认为最好不允许使用诸如 之类的简写形式background,至少在开始时是这样,这样您就可以轻松解析这些值。要求他们明确地写出background-color, background-image
  • 如果您需要 URL,则只允许相对 URL,并丢弃所有看起来不像 URL 的内容。无论如何记录这些问题,以便您可以改进解析器和验证器。
  • 解析时要非常严格,丢弃解析器无法理解的所有内容,即使它是有效的 CSS。换句话说,创建您自己的 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;
    }
}
Run Code Online (Sandbox Code Playgroud)