Ruby On Rails : Why do we need to html_safe string? : Why html tags not rendered?

What is html_safe? Why use that? Read this

Lets say, you have a feature in your application such that you have a text-area (Integrated with text-editor plugin) in your form and use can write markups. These markups are supposed to be rendered in the view as HTML Tags (Just like they appeared in TextEditor like CKEditor). Suppose you write

<p>
  <%= @job.description %>
  <%= @job.specification %>
</p>

Then you see in the view page, the markups you typed in text editor are visible in the page as just text. You see tags visible as text, are not rendered as DOM Elements. This is how Rails auto-escapes in views.

<p>
  <%= @job.description.html_safe %>
  <%= @job.specification.html_safe %>
</p>

Somewhere inside of Rails, this ERB template will be converted into a Ruby expression like this:

html = ''.html_safe
html << '<p>'.html_safe
html << '<br />'
html << '<br />'.html_safe
html << '</p>'.html_safe
html

If we eval the expression above, we will get this result:

<p>
  &lt;br /&gt;
  <br />
</p>

Advantage of Auto escaping of strings in the view

  • It auto closes the vulnerability of XSS as it escapes every string unless classified as safe.
  • It makes easy for ruby developer to print characters HTML tags, multi-spaces, and special characters intentionally in the view other wise they would have to know the escape-codes like `&nbsp;`, `&lt`, etc

A common mistake is to see those escaped angle brackets, and “improve” the helper by making everythinghtml_safe:

def group(content)
  "
#{content}
".html_safe end

We have just created a helper that vouches for its return value to be html_safe. By extension, it vouches forcontents to be safe, when it actually does not know anything about contents. If contents is unsafe user input, it will be rendered unescaped:

<div class="group"><script>alert('pwned!')</script></div>

Extra examples:

If you want to render an HTML tag that is inside a ruby string like below you cannot render it in the DOM by simple means.

<%= '<button class="button-red" id="mybutton" > Hey there</button>' %>.

You will only get the content in the string print as text not as DOM Element. To get the DOM Elements you need to tell Rails not to escape the characters like ‘space -> &nbsp, '>' -> &gt‘.

However, this works

<%= '<button class="button-red" id="mybutton" > Hey there</button>'.html_safe %>.

Conclusion:

html_safe tell Rails that Hey, this string is safe to be rendered other wise <%= will escape the characters

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s