Liquid Media's Apps

SafeErb and Rails security

Simon Willison linked to an article about SafeErb, a really cool tool that throws an exception whenever an Erb script tries to display a tainted string. In principle, this is a really useful tool to help prevent cross-site scripting attacks.

Unfortunately, as I've commented on those pages, too much of the Rails core code is bubbling up tainted strings. Since all strings that come from I/O sources are tainted, controllers and actions read from routes.rb are tainted, as are the list of javascript files in public/javascripts. Technically this is correct, but practically I think it is reasonable to assume that any files created by the application developer are "safe".

I can't actually say it's an error on Rails core to not be untainting strings more — really, who does? — but it would be really nice if they did! Right now, link_to will always generate a tainted link, even if every parameter supplied to the method is untainted. Same with other innocuous methods like javascript_include_tag. These problems make SafeErb essentially unusable in a Rails project unless you do as the author linked above does — adjust the methods to untaint the string before returning it.

For me, the lesson learned is a lesson in secure design. Rails could be even more powerful if it incorporated something like SafeErb from the ground up. If the Rails code untainted strings it knew were good, then the only bad strings would be those created by the users of a site, and application programmers would have to deal with those bad strings, every time. Some would argue that it's not DRY, but it's definitely secure!

Theoretically, I should propose this as a patch to Rails core, but I don't know how to go about winning support for such a wide-reaching change. I'm going to have to ponder this a bit. Suggestions?

Tagged cross-site scripting, rails, security, tainting, and xss.
blog comments powered by Disqus