Can't store html_safe in flash hash.

I believe due to this change: https://github.com/rails/rails/pull/13945#issuecomment-34090370 we’re no longer able to set html_safe strings in the flash message. Is this a bug? Does anyone have an opinion on the right way set a flash message with a link in it now?

-Justin

Instead of marking the flash value as html_safe it is better to proper sanitize it when presenting in your view. I believe <%= sanitize(flash[:notice) %> would work fine.

If the flash message was created entirely by program code with no user input, marking html_safe may be appropriate – and sanitizing may not be. Same as, say, running the output of a render :partial through sanitize – the html output may have only included tags that happen to be whitelisted by sanitize, so it may work, but it’s not really the right thing to do, and will fail in cases where the output had things not in sanitize’s whitelist.

Previously in our app, some parts of code supplied plain text to flash (in strings not marked html_safe), and expected it would be properly escaped. Other parts of code supplied .html_safe strings to flash, and expected it would be displayed as html without escaping.

Simply running everything through sanitize actually risks breaking both code paths – the things supplying non-html_safe strings may find that certain code that looks like html tags makes it through as html, when it was expected to be escaped. (Imagine a string “ The first part; The second part”). While the things that supplied properly html-safe strings (which already had tainted sub-strings properly escaped) may find that some HTML code that was intended to make it through – gets stripped by sanitize because it wasn’t on the whitelist.

In general, the html_safe mechanism is already pretty good at keeping things intended as HTML code (which were already produced in safe ways) separate from things intended as plain text (which shoudln’t just be sanitized, they should be escaped), and making sure they get combined properly (eg safe_join), etc.

But as of Rails 4.1, I guess this mechanism is unavailable for flash messages, simply marking a flash message html_safe or not. I miss it, it worked out well. I guess another workaround needs to be found for our program design, but simply passing everything through sanitize isn’t really it, I don’t think.

Jonathan

It doesn’t work on Rails 4.1 due the way flash are stored now by default.

In Rails 4.1 the default is to store cookies (and for consequence the flash) using JSON serialization, this serialization doesn’t store complex objects like ActiveSupport::SafeBuffer, a model instance, etc. This is the reason it doesn’t save the HTML safety of your string.

You still can use the old Marshal serialization configuring it in your application. That would bring back the possibility to store HTML safe strings on the flash but it is also less secure than the JSON serializer.