Not this chick. Sorry Rails, I love you and all, but you have now taken a governmental stance by trying to regulate the output of my HTML and for that, I must say: “Quit it!!”. If you haven’t caught up yet, Rails 3 takes HTML escaping into its own hands and instead of requiring you to use h() to escape your output, it’s now automagically escaped for you. Yay, that’s great right? No. Wrong. Because it means now anywhere you *didn’t* want your code escaped, you’ll have to use raw() or #html_safe. Also wrong because it enables bad, bad storage techniques.
First things first, you should be sanitizing your code prior to storage. Worried about someone adding JS to your public blog and breaking the site? Easy solution, throw away the <script> tag before writing to the db. There are plenty of tools to help with this, xss_terminate being one of them, there are even built-in Rails sanitizers. If you do it right on the way in, you won’t have to worry about it on the way out. Ok, so let’s say you potentially miss something? It happens, no one is perfect. That’s the perfect case to use escape trickery ( i.e. h() ) in the areas where you might be worried about your output.
In general, if you develop applications that resemble ones I build in anyway, you have more HTML output that *doesn’t* need to be sanitized than does. Sorry to whichever genius thought it would be a great idea to escape everything, but you made a bad decision. It’s okay, have a beer, wallow in your sorrows and then give users the option to turn this off. In the mean time, it’s easy to disable it yourself.
In config/initializers create a file, call it whatever, I called mine output_buffer.rb and all you need is:
class Object
def html_safe?
true
end
end
class String
def html_safe?
true
end
end
No related posts.
Related posts brought to you by Yet Another Related Posts Plugin.
This has been annoying me for quite some time. I spent some time trying to come up with a solution to disable it, but hadn’t thought about overloading it for all objects, interesting.
Their docs say nicely its “enabled by default”, but then there’s no documentation on how to disable it.
For me this feature is where the ‘rails way’ becomes a huge pita and makes me pissed off.
As you say – HTML sanitization has been a big deal for a long time, and the rest of us have apparently survived so far.
I think its a clever feature, and good to make budding web developers think harder, but there should still be an (embraced) way to disable it..
Thanks!
Completely agree Kevin, and after looking through the Rails source, there is no way to disable it. They simply have the methods html_safe? on String and Object explicitly set to false. It certainly makes me wary of what might be to come in future versions.
Actually, if you do it like that then the rails helpers will no longer properly escape URLs and values inside fields. A better way to switch it off escaping is here:
https://rails.lighthouseapp.com/projects/8994/tickets/5918-fix-erubis-non-escaping-sequence-patch#ticket-5918-1
While that is a viable alternative, for all intents and purposes, I am fine with escaping only when I know it needs to occur, as was the previous way of doing it (and something that in my 4+ years of developing Rails software have never once had to use).
Thank you Jen, I’m switching a big app from rails 2.3.2 to 3.1.3 and I found this enforcement of html_safe crazy!
This saved me a lot of time, thanks!
After using it in production for a while, did you find any drawbacks?
Paolo:
I’ve been using it for over a year now and have yet to run into a single issue in production… it’s been so long I’ve forgotten it’s even there, everything just works the old Rails way