Everything you know about html_safe is wrong.

As pointed out in the World of Rails Security talk at RailsConf this year, even the name is kind of crap. Calling .html_safe on some string sounds kind of like it would make said string safe to put in your HTML. In fact, it does the opposite.

Essentially, you need to ensure that every bit of user output is escaped. The defaults make things pretty safe: form inputs, links, etc. are all escaped by default. There are a few small holes, though.

Safe

  • link_to user_name, 'http://hired.com'
  • image_tag user_image, alt: user_image_title
  • HAML: .xs-block= user_text
  • ERB: <%= user_text %>

Not Safe

  • link_to user.name, user_entered_url
  • .flashbar= flash[:alert].html_safe # with, say, username included