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://github.com/NZKoz/rails_xss.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