views:

139

answers:

4

It seems ridiculous (and a violation of DRY) to have to type the h method all over the place in your view code to make it safe.

Has anyone come up with a clever workaround for this?

+4  A: 

DHH (creator of Rails) agrees with you. Rails 3 will escape output by default.

Larry K
Yes but I may have to type a thousand h calls before then :) I'm trying to find a gem or plugin that will alleviate this pain.
conor
I think this is probably more Yehuda than DHH. ;)
Luke Francl
+4  A: 

You could use Erubis as your ERB engine - which does offer auto-escaping. Their benchmarks mark it as 3x fast as ERB.

http://www.kuwata-lab.com/erubis/

The only problem is that its only for ERB, so if your Haml or some other templating language (like us) then you're SOL. I have used Erubis in the past and had no problems with it - before we switched to (the slower) Haml.

Cody Caughlan
Cool. That might just what I need. Only question, then, is whether the syntax is compatible with erb so if you need to switch a project back from erubis to erb, how painful would that be?
conor
Looks like my previous question is moot since they both implement the eRuby markup language. At least theoretically that would imply that I should be able to switch back and forth without changing my code.
conor
+3  A: 

You could use XSS_terminate which filters data going into your app (on save) instead of trying to catch it at the last possible second with h().

Theoretically, this should be sufficent and you shouldn't need to do anything else.

If you want to be paranoid (which in the context of security is not a bad thing), you should do both.

Mike Buckbee
I have used xss_terminate (disclosure: I wrote it) with Erubis's auto-escaping to get the double protection but it's hard to keep working with Rails as it updates. xss_terminate isn't perfect -- you still need to be aware of cases where you're emitting HTML from user input, but it reduces your attack profile dramatically over the Rails default.
Luke Francl
A: 

The Rails 3 approach is definitely the best on the view side because it explicitly keeps track of the safety of each string, which is ultimately what you need (taint mode) for a robust solution.

However there's another approach which is what ActsAsTextiled does. That is to redefine the attribute accessor to sanitize and cache the result so that you always get sanitized output by default. What I like about this as opposed to the xss_terminate approach is that it doesn't touch the user input at all so you get fewer complaints from users, and data won't be accidentally clobbered, and you can go and change the rules later if you overlooked something.

I liked the approach so much I wrote a plugin using the Sanitize gem ActsAsSanitiled. It doesn't give you blanket protection out of the box the way xss_terminate can, but it also avoids unwanted side effects. In my case comparatively few of the text fields are actually edited by users directly, so I prefer to audit them and explicitly declare them.

dasil003