views:

122

answers:

4

Hello!

I want to allow the users of a web app that I'm building to write their own CSS in order to customize their profile page.

However I am aware of this opening up for many security risks, i e background: url('javascript:alert("Got your cookies! " + document.cookies').

Hence I am looking for a solution to sanitize the CSS while still allowing as much CSS functionality as possible for my users.

So my questions if anyone anyone knows of a gem or a plugin to handles this? I've googled my brains out already so any tips would be really appreciated!

A: 

This is a tricky question. HTML encoding is not going to help for this type of XSS. HTML Purifier's CSS filter will only fix <div> tags, which isn't good enough. In this specific case the part of the CSS that makes this a security threat is the word "javascript", and the variation java\nscript

This quote is taken from the Sammy worm explanation (Sammy was the XSS worm that spread on MySpace):

myspace strips out the word "javascript" from ANYWHERE. To get around this, some browsers will actually interpret "java\nscript" as "javascript" (that's javascript). Example: <div id="mycode" expr="alert('hah!')" style="background:url('java script:eval(document.all.mycode.expr)')">

A simple, and secure solution to XSS in CSS would be the following line of Ruby:

css=css.gsub(/(java|script)/i, "") (Although is is very likely that stopping just the word "java" or just "script" would make xss in css impossible i matched both out of paranoia)

Rook
This regexp won't match java\nscript. `a*` means "any series of a's", not "an a followed by any number of characters".
Amnon
@Amnon good call, i changed my regex.
Rook
+4  A: 

Rails has a built-in css sanitizer

See http://apidock.com/rails/ActionView/Helpers/SanitizeHelper/sanitize_css and its parent http://apidock.com/rails/ActionView/Helpers/SanitizeHelper/sanitize

> ActionController::Base.helpers.sanitize_css('background:#fff')
=> "background: #fff;" 
> ActionController::Base.helpers.sanitize_css('javascript:alert("garr");')
=> "" 
mylescarrick
Ok, thank you! But as I understand it this method is only used to sanitize a style attribute on a HTML element. It can't be used to sanitize an entire stylesheet…?
Erik
It should be just the same - one line or a stack of lines... it won't matter.
mylescarrick
A: 

Sanitizing CSS could be simple if you start using something like LESS. Less offers a tool that parses CSS and raise an exception if the CSS is not valid. This will both make sure the CSS the user entered is valid (feature!) and avoid any dangerous injections.

marcgg
mylescarrick
@mylescarrick: They don't have to write less, they can just write plain CSS.
marcgg
I installed the less gem and did a quick test to parse "bad code" (i e javascript code in a background attribute), however Less didn't remove this. Maybe there was some argument to the Less.parse method that I missed…?
Erik
A: 

Here is something i came across:

Liquid is a template engine which was crafted for very specific requirements

  • It has to have simple markup and beautiful results. Template engines which don’t produce good looking results are no fun to use.
  • It needs to be non-evaling and secure. Liquid templates are made so that users can edit them. You don’t want to run code on your server which your users wrote.
  • It has to be stateless. The compile and render steps have to be separate, so that the expensive parsing and compiling can be done once; later on, you can just render it by passing in a hash with local variables and objects.
  • It needs to be able to style emails as well as HTML.

Check it out here: http://github.com/tobi/liquid

Shripad K