Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

Prevent Cross-site Scripting Attacks with Rails 2.3.5 and rails_xss

Earlier this week, the Rails core team released Rails 2.3.5 which introduces a major new feature: support for automatic cross-site scripting protection via the rails_xss plugin. rails_xss switches the default behavior of Rails to automatically escape all unsafe strings emitted into the view.

Why does this matter? Well, in order to prevent cross-site scripting attacks, user-entered data displayed by an application must be filtered to escape HTML tag characters so that they are displayed rather than used as mark-up. In previous versions of Rails the h helper method must be explicitly called to escape a string. This means that if you miss even one string in your application you’ve left a potentially dangerous security hole.

rails_xss enhances the String class with the concept of HTML safety. By default a string is assumed not to be HTML safe. Each time a string is copied into the view, it is evaluated for safeness and escaped if not safe. Strings can be explicitly set safe by calling the html_safe! method.

Adding this plugin to an existing application should be pretty painless as h will still return escaped strings. The plugin also provides the view helper method raw which acts as the opposite of h: strings passed through raw will be copied into the response body without any escaping.

Helper methods which emit HTML may need to have html_safe! called on the resulting string or use the raw helper method. Another possible gotcha is that in testing I noticed some small kinks. The largest being that button_to‘s output isn’t set to HTML safe so it will dump a bunch of HTML on the page rather than the button. This can be worked around by using the raw helper along with button_to, and I assume it’ll be fixed shortly.

rails_xss also changes the default template handler from ERB to Erubis so you may see some performance improvement in your views as Erubis is said to be three times faster than ERB. The escaping behavior and Erubis will both be default in Rails 3.0.

To get started:

  • Upgrade to Rails 2.3.5
  • gem install erubis
  • script/plugin install git://

After installation your application will output strings with escaping by default:

<%= "<h1>unsafe string</h1>" -%> -- Escaped
<%= h "<h1>unsafe string</h1>" -%> -- Escaped
<%= "<h1>unsafe string</h1>".html_safe! -%> -- Not escaped
<%= raw "<h1>unsafe string</h1>" -%> -- Not escaped

  1. William Pietri says:

    Wow, that’s great to hear. It always blew my mind that Rails didn’t work this way from the start. In other languages I’ve often ended up with something like an HtmlString class to signal the (few) strings that are actually raw HTML, rather than honest strings; sounds like this is reasonably close. Thanks for posting this.

  2. Yarrow says:

    Is the third line accurate? From the article and the rails_xss README I’d have expected the .html_safe! version to be “Not escaped”.

  3. John Pignata says:

    Yarrow – No, that is totally a typo. Thanks for the catch! I’ve updated it in the post.

  4. John Pignata says:

    There’s an interesting thread on the rails-core list about rails_xss and what it means for plugin/gem authors who want to support it. Users have reported problems with will_paginate and rails_xss cooperating.

  5. Anonymous says:

    Are you running it on this site? Because if you are, it is rather broken. has a potential XSS on it since you do allow user-entered invalid Unicode characters to be output unfiltered. This can trip up IE’s UTF-8 parser which can lead to script injection.

Post a Comment

Your Information (Name required. Email address will not be displayed with comment.)

* Copy This Password *

* Type Or Paste Password Here *