Posted over 11 years ago. Visible to the public. Repeats.

Don't mix Array#join and String#html_safe

You cannot use Array#join on an array of strings where some strings are html_safe and others are not. The result will be an unsafe string and will thus be escaped when rendered in a view:

unsafe_string = '<span>foo</span>' safe_string = '<span>bar</span>'.html_safe [unsafe_string, safe_string].join(' ') # will incorrectly render as '&lt;span&gt;foo&lt;/span&gt;&lt;span&t;bar&lt;/span&gt;'


The solution is not to call html_safe on the joined array and if you thought it would be, you don't understand how XSS protection works in Rails. Calling html_safe on the joined array will incorrectly bless the complete string as safe:

[safe_string, unsafe_string].join(' ').html_safe # will incorrectly render as '<span>foo</span><span>bar</span>' with unescaped tags


Rails >=3

safe_join([unsafe_string, safe_string], ' ') # will correctly render as '&lt;span&gt;foo&lt;/span&gt; <span>bar</span>'

Note: The second argument is the separator, that could also be something like content_tag(:br).

If you need to use safe_join() in a model, you need to include ActionView::Helpers::OutputSafetyHelper.

Rails 2

Roll a custom join method that is aware of Rails XSS protection. Copy the following code to config/initializers/xss_aware_join.rb:

Array.class_eval do def xss_aware_join(delimiter = '') ''.html_safe.tap do |str| each_with_index do |element, i| str << delimiter if i > 0 str << element end end end end

You can now say:

[unsafe_string, safe_string].xss_aware_join(' ') # will correctly render as '&lt;span&gt;foo&lt;/span&gt; <span>bar</span>'

Your development team has a full backlog of feature requests, chores and refactoring coupled with deadlines? We are familiar with that. With our "DevOps as a Service" offering, we support developer teams with infrastructure and operations expertise.

Owner of this card:

Henning Koch
Last edit:
almost 2 years ago
by Henning Koch
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Henning Koch to makandra dev
This website uses short-lived cookies to improve usability.
Accept or learn more