views:

404

answers:

4

In my application I am allowing users to upload their css style sheets so they can applied to templates. The css is written as an internal style sheet, because at this time I would not like to expose the css style sheet to other users.

That creates room for users to include malicious code into the css file. Initially my plan was to convert all '<' and '>', but that is needed in the css syntax. I am after a white list solution, since it won't be feasible to exhaustively eliminate unwanted characters.

Any suggestions for implementing security measures to this scenario?

A: 

Use CDATA and escape the terminating sequence (]]>). I'm not sure about browser compatibility, though.

Example (untested):

<?PHP

function strReplaceAll($needle, $replacement, $haystack)
{
    // Check for infinite loop.  (NOT FOOL PROOF!)
    if(strpos($replacement, $needle) === FALSE)
        return;

    $numReplacements = 42;

    while($numReplacements)
    {
        $haystack = str_replace($needle, $replacement, $haystack, &$numReplacements);
    }

    return $haystack;
}

?>

<style type="text/css">
/*
<![CDATA[
*/

<?PHP echo sstrReplaceAll(']]>', '', $userCss); ?>

/*
]]>
*/
</style>
strager
I think malicious users could have a string like " /*]]>*/ malicious.stuff /*<![CDATA[*/ " as $userCss. That could be a way around that.
Marcel Tjandraatmadja
@Marcel, It is of course filtered. See the str_replace.
strager
A user could circumvent that protection easily by typing: ]]]>]]]>>
Nicholas
@Nick, Good point. I guess the replace could be done many times until no change to the document is made.
strager
@Nick, Corrected (I hope). Thanks for your input.
strager
+1  A: 

I implemented a filter that replaces all < characters to &lt;. The reason is that CSS does not need the < character; the only character it needs is the > which is used for child selectors.

That way users cannot open tags to write malicious code.

I am more than happy to consider any other/better solutions.

Marcel Tjandraatmadja
+4  A: 

You should definitely also filter out at least IE expressions and FF -moz-binding properties... both can be used to run (potentionally malicious) javascript using css.

This cheat sheet contains the most obvious XSS tactics, including some CSS ones.

The safest solution would probably be whitelisting as you suggested (if it is acceptable to limit users to only use whitelisted properties).

kkyy
Can you please elaborate more on that? Thanks!
Marcel Tjandraatmadja
See http://tinyurl.com/cru7rj
kkyy
Great reference. Thank you.
Marcel Tjandraatmadja
Nice note you made about XSS and embedded Javascript.
strager
+1  A: 

Dont allow users to upload a CSS FILE, make an interface that generate the CSS files dynamicly based on the options selected by the user. The options you allow. then you can make a fisical CSS file or you can make a dynamic application who writes CSS based on that configuration, this avoid to have lots of CSS files on the server... its another approach and you dont need to check every posible XSS exploit, its more easy to define what is allowed than parsing CSS and rejecting some dangerous code.

gonxalo