Suppose I have the following string
@x = "<a href="#">Turn me into a link</a>"
In my view, I want a link to be displayed. That is, I don’t want everything in @x to be unescaped and displayed as a string. What’s the difference between using
<%= raw @x %> <%= h @x %> <%= @x.html_safe %>
Considering Rails 3:
html_safe actually “sets the string” as HTML Safe (it’s a little more complicated than that, but it’s basically it). This way, you can return HTML Safe strings from helpers or models at will.
h can only be used from within a controller or view, since it’s from a helper. It will force the output to be escaped. It’s not really deprecated, but you most likely won’t use it anymore: the only usage is to “revert” an
html_safe declaration, pretty unusual.
Prepending your expression with
raw is actually equivalent to calling
to_s chained with
html_safe on it, but is declared on a helper, just like
h, so it can only be used on controllers and views.
“SafeBuffers and Rails 3.0” is a nice explanation on how the
SafeBuffers (the class that does the
html_safe magic) work.
I think it bears repeating:
html_safe does not HTML-escape your string. In fact, it will prevent your string from being escaped.
<%= "<script>alert('Hello!')</script>" %>
into your HTML source (yay, so safe!), while:
<%= "<script>alert('Hello!')</script>".html_safe %>
will pop up the alert dialog (are you sure that’s what you want?). So you probably don’t want to call
html_safe on any user-entered strings.
The difference is between Rails’
raw(). There is an excellent post by Yehuda Katz on this, and it really boils down to this:
def raw(stringish) stringish.to_s.html_safe end
raw() is a wrapper around
html_safe() that forces the input to String and then calls
html_safe() on it. It’s also the case that
raw() is a helper in a module whereas
html_safe() is a method on the String class which makes a new ActiveSupport::SafeBuffer instance — that has a
@dirty flag in it.
Refer to “Rails’ html_safe vs. raw“.
Marks a string as trusted safe. It will be inserted into HTML with no additional escaping performed.
"<a>Hello</a>".html_safe #=> "<a>Hello</a>" nil.html_safe #=> NoMethodError: undefined method `html_safe' for nil:NilClass
rawis just a wrapper around
rawif there are chances that the string will be
raw("<a>Hello</a>") #=> "<a>Hello</a>" raw(nil) #=> ""
A utility method for escaping HTML tag characters. Use this method to escape any unsafe content.
In Rails 3 and above it is used by default so you don’t need to use this method explicitly
The best safe way is:
<%= sanitize @x %>
It will avoid XSS!
In Simple Rails terms:
h remove html tags into number characters so that rendering won’t break your html
html_safe sets a boolean in string so that the string is considered as html save
raw It converts to html_safe to string
Short and Simple
Let’s assume we can’t trust user input.
user_input.html_safe # asking for trouble
user_input.html_escape # or
h(user_input) # in some view
Inputs we control:
that should be fine. but be careful what your trusted inputs are. They must only be generated from your app.