Potential Circumvention of CSRF Protection in Rails 2.1

There is a bug in all 2.1.x versions of Ruby on Rails which affects the effectiveness of the CSRF protection given by protect_from_forgery.

By design rails does not perform token verification on requests with certain content types not typically generated by browsers. Unfortunately this list also included ‘text/plain’ which can be generated by browsers.


Requests can be crafted which will circumvent the CSRF protection entirely. Rails does not parse the parameters provided with these requests, but that may not be enough to protect your application.

Affected Versions

  • All releases in the 2.1 series
  • All 2.2 Pre Releases


The upcoming 2.1.3 and 2.2.2 releases will contain a fix for this issue.

Interim Workarounds

Users of 2.1.x releases are advised to insert the following code into a file in config/initializers/

> Mime::Type.unverifiable_types.delete(:text)

Users of Edge Rails after 2.2.1, should upgrade to the latest code in 2-2-stable.

The patch for the 2.1.x series is available on github. This will also apply cleanly to 2.2 pre-releases prior to this changeset released on Thursday November 13th at 11:19:53 2008 CET. Users with edge-rails checkouts after that date, are advised to upgrade to the latest code in 2-2-stable.

Thanks to Steve from Coderrr for reporting this issue.

New Rails 2.2 i18n defaults

I just reduced the housework needed to setup a new Rails application with i18n. All new applications will ship with a config/locales directory that’s automatically wired up in the load path for i18n. So you can just drop .yml or .rb locale files in there and they’ll be instantly available for translation.

There’s also a sample config/locales/en.yml file in there to give you a starting point. In addition, the initializer is now wired up through the Rails config. The new default environment.rb provides these pointers:

# The internationalization framework can be changed 
# to have another default locale (standard is :en) or more load paths.
# All files from config/locales/*.rb,yml are added automatically.
# config.i18n.load_path << Dir[File.join(RAILS_ROOT, 'my', 'locales', '*.{rb,yml}')]
# config.i18n.default_locale = :de

So on a fresh Rails 2.2 application, you’ll be able to do see it all wired up out of the box (the :hello key is from the config/locales/en.yml demo file):

$ ./script/console
>> I18n.t :hello
=> "Hello world"

Rails 2.2 final is just around the corner. We’ve been ironing out the last bugs and added the last amount of polish to make this a kick ass release. Also, work on 2.3 / 3.0 has already begun in master as well since we’ve branched for 2.2 a while back.

Rails 2.2 RC2: Last stop before final

Rails 2.2 has been baking for long enough now. This is the last taste before the goodies are served. So please install and check it out. See if you can find any regressions or bugs in any of the new stuff, so we can have it all delicious by the time we ring the dinner bell (ok, ok, I’ll put down the food metaphor now).

This release also conciedes with the fact that we’ve branches 2-2-stable, which means that master is now actually targeting Rails 2.3/3.0. There’s also a tag available for this RC as v2.2.1.

If you missed RC1, have a look at the Rails 2.2 release notes to see the major additions. You can see what’s new since RC1 in these two This Week in Edge Rails.

To install, you must first have RubyGems 1.3.1:
gem update --system.

Then you can:
gem install rails -s http://gems.rubyonrails.org


This Week in Edge Rails

The important news in edge Rails this week is the imminent release of Rails 2.2.1 – otherwise known as Rails 2.2 RC2. Getting ready for this release did lead to some significant changes in the Rails codebase.

First, it’s very likely that you’ll need to upgrade rubygems to run RC2: the required version of rubygems is now 1.3.1, which was just released yesterday. This dependency is part of the continued work to make vendored gems useful and stable. You may find that updating rubygems is less than smooth, depending on your current version; check out this article if you have any trouble. commit

The Rails routing engine has seen some serious work over the past week as well. For starters, Jeremy Kemper committed several fixes to the core routing engine that cut down on object creation and RegExp creation, trimming memory use. commit commit There are also new :only and :except options for map.resources, which can help cut down memory use if you have a lot of resource routes – see these articles for details (though there have been some tweaks in the way nested limited routes work after those were written). commit commit commit

The new ActiveRecord connection pooling code has seen some tuning as well, making it more efficient in development model and avoiding some issues with the Oracle adapter. commit

Polymorphic URLs now behave more intuitively if one of their parameters is nil. For example, a call to polymorphic_path([project, filter, @issue]) with a nil filter now returns project_issue_url instead of a NoMethodError. commit

The request forgery protection feature in Rails has been tightened up so that it only applies to HTML-formatted content requests. There is substantial discussion on the Lighthouse ticket that led to this change, but the bottom line is that the old implementation had some bugs, notably making destroy actions inaccessible via XML. Other types of requests are protected by other means – for instance, the same origin policy on AJAX requests substitutes for request forgery protection there. commit

This Week in Edge Rails

Rails, as you probably know, is under active development. So, for those of you who don’t have time to read every commit to the source, we’ve decided to revive this section of the weblog. This time around, I’m covering 3 weeks of commits: the time since Rails 2.2 RC1 (otherwise known as Rails 2.2.0) was released. Though there aren’t any major new features being added as Rails drives towards the 2.2 release, that doesn’t mean the source has been completely quiet: there have been about 75 commits in that three-week period. Here’s a look at some of those changes.

In the run-up to 2.2, we’re seeing a batch of little bug fixes, as people try to ensure quality in the release. These include:

  • Squashing a binary data corruption bug that surfaced in the PostgreSQL adapter. commit
  • The regex behind redirect_to can now accept a wider variety of URL schemes, making it possible to redirect to some destinations that were previously inaccessible. commit
  • A regression in date_select and datetime_select that could raise a Null Pointer Exception under some circumstances has been fixed. commit
  • The sanitize helper has been fixed to avoid double escaping already properly escaped entities. commit
  • FormTagHelper has been stopped from generating illegal HTML if the name contains square brackets. commit
  • A memory leak was squashed in Active Record scoped methods. commit

Some of the major features for 2.2 have been getting fine-tuned as well. There’s been work to clean up some loose ends in the thread safety department, and changes to make the I18n backend reload its translations in development mode. The included Prototype bits were bumped to the latest release. The code for configuring, loading, and vendoring gems has had some attention, and the code for maintaining database connection pools has come in for some fine-tuning as well.

Just because we’re in feature freeze doesn’t mean that a few new features can’t sneak in:

  • The current_page method is a bit more reliable now in that it ignores options you don’t explicitly supply (making it more friendly to URLs that use the query string for pagination and the like). commit
  • The default logging has been cleaned up to be less chatty: you’ll see fewer duplicate log messages as Rails goes about its business. commit
  • The render method now takes a :js option to allow you to directly render inline JavaScript without using RJS. commit
  • If you’ve got a current (Ruby 1.8.7 or greater) version of Ruby, Action Mailer turns on STARTTLS if the server supports it; this makes Action Mailer compatible with GMail without the need for plugins. commit

One final note: I’m deliberately not trying to cover every single commit here; just those ones that struck me as most interesting. But if I left out something that you think is highly significant, feel free to add a pointer in the comments!

Rails Guides Wants You

If you haven’t looked at the state of Rails documentation lately, it’s time to look again. The new Ruby on Rails Guides page includes 14 separate guides for Rails developers, with topics ranging from “Getting Started” to routing, security, testing, and debugging. That’s over 70,000 words of help content for Rails users that didn’t exist two months ago when we launched the Rails Guides project.

But we’re not done yet! We’re starting phase 2 of the Guides project, and planning a fresh batch of content to add to what’s already there. Our goal is to have a single page where you can find all of the information you need to be an effective Rails developer. Remember, though: this is open source. That means we want your help too!

Here’s what you can do to get involved:

  • Read about the process of and rewards for contributing on the Hackfest page.
  • Check the list of available tickets in our Lighthouse project, and sign up to write a guide.
  • Submit corrections, suggestion, bugs, or patches for the existing guides. You’ll find a link to the relevant Lighthouse ticket at the bottom of each guide.
  • Let us know what other guides you think should be added – whether you want to write them, or just hope that someone else will. Just leave a note in the comments here and we’ll get your idea into the process.

You’ll usually find some of the documentation team hanging around in #docrails on IRC. Come join us and help the community!

3 Weeks in Rails (October 29, 2008)

It’s been 3 weeks (I know I’ve been slacking). However, it’s time to write out another summary of information that any Rails developer might want to know about. Detailed audio versions of these notes can be found on the Rails Envy Podcast #51, #52, and #53.

You may already be aware that Rails 2.2 RC1 was released last Friday. For a glimpse at the new features you can read through the Release Notes. However, if you’re looking for something more comprehensive check out the Envycast on Ruby on Rails 2.2^ or the What’s New PDF by Carlos Brando.

Rails 2.0.5 and Rails 2.1.2 were also pushed in the last few weeks, mostly just plugging up a few small security concerns. If you’re on 2.x, you should probably take the time to upgrade.

If you’re taking advantage of the localization features of Rails 2.2, there are two libraries you should probably be aware of. First, Diego Carrion recently created a fork of restful_authentication where he added full support for i18n. Secondly, Karel Minarik recently released a plugin for doing localized_country_select so you can display countries the appropriate language.

If you need your Rails application to receive emails, one way to do it is to use gmail IMAP. John Nunemaker wrote up a nice walkthrough showing all the scripts need to parse email out of gmail.

Hosting, Performance, and Tuning

With Rails 2.2 thread safety, you might assume that brings a performance boost for everyone. However, this is not always the case and Pratik Naik explains why.

Ilya Grigorik wrote a blog post about Scaling Rails with MYSQL Plus where he uses the Non-Blocking MySQL driver from Neverblock to get some increased performance out of ActiveRecord which is quite impressive.

If you need to implement full text search in your Rails application, and you are already thinking Sphinx, you may want to check out the Thinking Sphinx PDF by Pat Allan over on Peepcode.

Library News

If you’re a fan of resource_controller (skinny REST controllers) and Shoulda you shoulda definitely check out the starter app by James Golick called Blank.

The next time you need to build a “Software As A Service” website (like basecamp), check out Service Merchant. This gem sits on top of Active Merchant and gives you everything you need to do Subscription Billing.

Do you ever forget your Rails routes? There’s always the “rake routes” command, but that’s not very user friendly. You might want to check out Vasco. Vasco is a Route explorer for Rails which provides a nice web interface to browse through and test all your Rails routes.

If you ever need to build a Rails application which is accessible on multiple domains or multiple paths (like foo.com or bar.com or a.com/foo) then take a look at the Rails Proxy Plugin by Sean Huber. This plugin allows you to dynamically respond to proxied requests by detecting the incoming path and properly setting the session domain, default host, and relative url root.

If you need an easy way to test your plugin which extends ActiveRecord, check out acts_as_fu, which aside from it’s unfortunate name, is pretty slick.

If you came over from PHP, you’re probably familiar with phpMyAdmin. One of the Rails Rumble teams made a Ruby version of phpMyAdmin that’s definitely worth checking out if you’re missing a quick web interface to your db.

Event News

The Rails Rumble is over and you only have 3 more days to vote (voting closes on Midnight November 1st). Cast your vote! It’s good practice for next Tuesday (least in the US).

If you’re over in London, Ruby Manor is taking place November 22nd. Looks like it’s going to be a fun unconference type of event.

Lastly, Rubyconf is next week here in Orlando, Florida where it’s been kinda chilly lately. Definitely pack something warm just in case, and see you next week!

Image Credit: Blue Sky on Rails by ecstaticist, Analog Solutions 606 Mod by Formication, RailsConf Europe 2006 by Paul Watson, Rainbow by One Good Bumblebee
^ In the interest of full disclosure, I do produce Envycasts, and profit from the sale of the screencasts.

Rails 2.2 RC1: i18n, thread safety, docs, etag/last-modified, JRuby/1.9 compatibility

Rails 2.2 is almost ready for its final release, but before we christen the gems, we’d like to have everyone test out a release candidate. Rails 2.2 is a major upgrade that includes a wealth of new features and fixes.

Chief inclusions are an internationalization framework, thread safety (including a connection pool for Active Record), easier access to HTTP caching with etags and last modified, compatibility with Ruby 1.9 and JRuby, and a wealth of new documentation.

Mike Gunderloy has compiled an exhaustive list and walk-through of many of the interesting new features for the Rails 2.2 release notes.

To help test the Rails 2.2 release candidate, please install with:
gem install rails -s http://gems.rubyonrails.org -v 2.2.0

Hopefully there will not be too much folly in the RC and we can quickly move to a final release. But it requires your help to get there.

Note that this release is called 2.2.0, not 2.1.99 as our previous naming scheme would have dictated. So the final release of Rails 2.2 will actually be 2.2.1 (if we only need one RC).