如何在PHP中基于白名单的CSS过滤 [英] How to preform whitelist-based CSS filtering in PHP

查看:140
本文介绍了如何在PHP中基于白名单的CSS过滤的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在网站上工作,我想让用户能够输入自定义的CSS,然后公开显示。

I am working on a site and I would like to make a user able to enter custom CSS into that will be publicly displayed.

但是,处理XSS攻击可以通过CSS,我想找到一种方法来清理CSS输出,类似于 HTML Purifier 通过解析CSS,根据白名单运行解析的CSS,然后根据解析的白名单CSS输出新的样式表。

However, seeing as a good deal of XSS attacks can be preformed through CSS, I would like to be able to find a way to "clean" the CSS output, similar to how HTML Purifier works, by parsing the CSS, running the parsed CSS against a whitelist, and then outputting a new stylesheet based on the parsed and whitelisted CSS.

有没有像这样的图书馆?如果没有,是否有一个CSS解析库可以用来创建自定义实现?

Is there already a library like this out there? If not, is there a CSS parsing library that can be used to create a custom implementation?

推荐答案

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

I guess you're going to write your own CSS parser and filter, so here's what I'd consider, although I've never done such a thing:


  • 您的用户可以使用的可接受的CSS属性的(白色)列表。喜欢: color font-family

  • 最好不要允许短手形式,例如 background ,至少在开头,以便您可以轻松地解析值。要求他们明确写入 background-color background-image

  • 如果您需要网址,则只允许使用相对网址,并舍弃一切看起来不像网址的内容。

  • 在解析中非常严格,舍弃解析器不理解的所有内容,即使它是有效的CSS也是如此。请记住这些问题,以便您可以改进您的解析器和验证器。

  • Make a (white) list of acceptable CSS properties that your users can use. Like: color, font-family.
  • I believe it might be better to not allow short-hand forms such as background, at least in the beginning, so that you can easily parse the values. Require that they explicitly write background-color, background-image.
  • If you want URLs, only allow relative URLs, and discard everything that doesn't even closely look like a URL. Log these issues anyway, so that you can improve your parser and validator.
  • Be very strict in your parsing, discard everything that your parser doesn't understand even if it would be valid CSS. In other words, make your own CSS subset.

解析时,最难的部分是解析复杂的CSS选择器

When parsing, the hardest part would be the parsing of complex CSS selectors. But you can impose your own subset here too.

这里有一些(伪)代码,也许它会以某种方式帮助你:

Here's some (pseudo)code, maybe it will help you somehow:

<?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;
    }
}

这篇关于如何在PHP中基于白名单的CSS过滤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆