Rails 3 and html_safe

Is it just me or is html_safe a massive pain in the arse? Just trying to do a simple helper.

def messages   messages = ''   [:error, :notice].each do |t|     if flash[t]       messages << content_tag(:p, flash[t], :class => t)    end   end   unless messages.blank?      content_tag(:div, messages)   end end

cause an enormous amount of aggravation. I tried for hours to try and find why it was escaping everything.

def messages   messages = ''.html_safe   [:error, :notice].each do |t|     if flash[t]       messages << content_tag(:p, flash[t].html_safe, :class => t)    end   end   unless messages.blank?      content_tag(:div, messages)   end end

It would be nice if you could just html_safe right at the end of the method but oooooh no.

Discuss?

Rob Lacey wrote:

Is it just me or is html_safe a massive pain in the arse? Just trying to do a simple helper.

Are you having an actual problem with it, or are you just complaining?

If it's the latter, then I'll inject that it's a heck of a lot less of a pain than having to remember to wrap every potentially unsafe user input with the "h" method. On top of being less painful, it's also much safer to be secure by default.

If you have any suggestions on a better implementation of html_safe then this is the wrong forum to make those suggestions. Instead make them to the Rails core forum where they belong.

I guess its a bit of a whinge as well as to gauge other people's opinions on it. Personally I haven't used the 'h' method a great deal in the past 4 years of developing with Rails, I guess because our validation generally doesn't allow for html being injected into our database. But of course its always possible.

Its a tricky one as I might expect that calling html_safe on a string that has already been escaped because its deemed to be unsafe, would actually unescape it again. As it stands you end up with calling html_safe in lots of different places on every new string that's introduced along the way, and therefore repeating yourself a lot.

RobL

Rob Lacey wrote:

I guess its a bit of a whinge as well as to gauge other people's opinions on it. Personally I haven't used the 'h' method a great deal in the past 4 years of developing with Rails, I guess because our validation generally doesn't allow for html being injected into our database. But of course its always possible.

I have a feeling you're affording yourself a lot more confidence than deserved. Just because you haven't been hacked yet, doesn't mean your system is truly secure. It more likely means that, so far, nobody has been interested in hacking your system. Hopefully that won't happen to you, but if you're not "generally" using the h method, I'm betting you have holes in your security (well less so now that you're moving to Rails 3.0).

"Generally" just doesn't cut it when it comes to security. Security is like a chain, in that the integrity of the chain depends on its weakest link. It doesn't matter if you have a thousand perfectly strong links, if just one of them is weak then your system is vulnerable.

In my opinion it is far better to default secure, and then tell the system when you want to loosen security when necessary. This is what html_safe provides us.

Its a tricky one as I might expect that calling html_safe on a string that has already been escaped because its deemed to be unsafe, would actually unescape it again. As it stands you end up with calling html_safe in lots of different places on every new string that's introduced along the way, and therefore repeating yourself a lot.

Most developers will be calling html_safe far less often than the old h method. So I'll gladly take that trade-off.

Also, don't make snap judgments on an implementation such as html_safe. If you sure that it works the way you have described it, then fine. Otherwise you're just going to confuse people. I highly recommend you find a blog written by someone who actually knows how html_safe works. I think you'll be pleasantly surprised by both its function and its implementation.

Don't think that I have written off html_safe as worthless as I think you might have. I see its value of course. I'm not sitting here being cocky either. Lets just say that I've found using html_safe so far to be tricky, even it it does force me to be clear at every stage what may or may not be harmful strings.

Its interesting to note that the solution to my problem was

messages = '' messages << content_tag(:p, 'dave') #=> &lt;p&gt;dave&lt;\p%;gt;

message = ''.html_safe message << content_tag(:p, 'dave') #=> <p>dave</p>

because an empty string is considered not to be html_safe and concatenating to it made the resulting string not html_safe. My concern was more that the original source of the unsafe html was a bit confusing.

RobL