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?
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?
DHH (creator of Rails) agrees with you. Rails 3 will escape output by default.
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.
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.
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.