Struggle with Ruby on Rails String.to_json
Coffee break at work and I thought I could share some experience with Ruby on Rails to_json while consuming the liquids. My collegue experienced problem with following kind of code:
update_page do |page|
page.replace_html('content_div', :partial => 'content')
end
There’s nothing special in this code, except the fact that our partial returns javascript to update other elements (in this case it was few buttons which were within the partial itself). The problem is that the replace_html renders the partial into a string, which in return gets transformed into javascript string argument with Rails’ String.to_json and that method does not perform correct escaping when the string contains </script> tag.
Even though such tag normally wouldn’t need escaping the problem appears within the browser. I’m sure there are differences in browsers, but we are using Firefox which intepretes the literal </script> within the javascript string as being the end of the script block. That results incorrect behavior for evaluating (or infact not doing any evaluating of remaining) javascript.
We could have moved the javascript separate from the partial, but it would break a lot of other code and make things less easy to manage when the context specific javascript would need to be outputted separately from the partial. Instead my collegue and I did some XP programming and dug up how the to_json works and implemented replacement for the to_json to do correct escaping for browser’s parser. Here’s the code we inserted into our enviroment.rb file (that’s the place at the moment we keep our class extensions):
class String
alias original_to_json to_json
def to_json
original_to_json.gsub('</script>', '\<\/script>')
end
end
It’s a pretty simple piece of code calling the original to_json and doing additional escaping for the script tag. After booting mongrel, everything worked as it was supposed to work. This is something I could really see to be fixed within the Ruby on Rails core itself because such flaw in escaping could easily open security holes for javascript injection hacks and it doesn’t break anything as being just javascript string escaping.
August 20th, 2007 at 18:03
I used Regexp.escape(original), seem to work for me but not so sure, I’m newbie in Rail and Json