giant robots smashing into other giant robots

Written by thoughtbot

lolconomy

Clearance 0.16.3 fixes a password reset vulnerability

The new release of Clearance works around the latest Rails SQL injection. Upgrade to Clearance 0.16.3 for the security fix.


gem 'clearance', '~> 0.16.3'

Background

In Clearance we generate a confirmation_token when you forget your password, and clear it when you successfully reset your password. In the controller we find the user like this:


@user = User.find_by_id_and_confirmation_token(params[:user_id], params[:token])

This approximately translates to this ARel query:


User.where(:id => params[:user_id], :confirmation_token => params[:token])

Normally this generates perfectly safe SQL:


SELECT users.*
FROM users
WHERE users.id = 1
AND users.confirmation_token = 'hello'
LIMIT 1

Exploit

If params[:token] is a list with one nil element, the generated SQL is closer to this:


SELECT users.*
FROM users
WHERE users.id = 1
AND users.confirmation_token IS NULL
LIMIT 1

That is, if you can get params[:token] to produce [nil] then you can become any user without a confirmation_token.

Prior to Rails 3.2.5, this URL would generate [nil]:

/users/1/password/edit?token[]

We catch this in Clearance now.

Fix

Upgrade to Clearance 0.16.3. If you are using Rails 3.2.5 or above then you do not need to upgrade Clearance to get this fix.

Acknowledgements

Thank you to Ben Murphy for bringing this to our attention in a professional manner, and to the Rails team for fixing it quickly.

dancroak

Clearance: Rails authentication with email and password

imageAuthentication is a common pattern in Rails apps. Thus, there have been many authentication plugins. We’ve tried acts_as_authenticated and restful_authentication over the years.

We found that user authentication is hard to generalize. Most abstracted authentication plugins had both too much and too little for us.

We then tried writing authentication from scratch on our clients’ Rails apps for about a year. We felt better about test coverage but it was still a pain to re-write similar code. App after app, we talked about extracting common code into a library. Each time we resisted.

After a while, we thought that maybe 60% of authentication could be re-used. We extracted Hoptoad’s authentication, then merged code from two of our clients’ apps. We named the gem Clearance.

On the first attempt, we went overboard on re-use. We backed off and wrote hooks in places we were finding logical extension points. For the past few months, patches have trickled in from Github and we’ve carefully included code that fits in the “60%”.

We recently started a new project. In the process, we’ve polished the gem and are happy to announce its official release.

Clearance

  • Sign up
  • Confirm email
  • Sign in
  • Sign out
  • Reset password

Get it on Github.

Modules, Shoulda, and Factory Girl

Clearance is focused on maintainability of your application’s authentication code.

  • Include comprehensive Shoulda and Factory Girl tests in your Rails app’s test suite
  • Encapsulate authentication logic in modules which are included in your controllers, models, and tests.

This approach keeps your Rails application’s code clean and alerts you if you ever break your authentication code.

Due to the work we’ve been doing to make Shoulda test framework-agnostic, you will be able to use RSpec in the 0.5.0 release of Clearance.

Test::Unit and Cucumber features are also supported:

script/generate clearance
script/generate clearance_features

Conventions

To keep our approach simple, we made a series of design decisions:

  • User model required.
  • User model uses attr_accessible.
  • Authenticate by email (not username) and password.
  • Vocabulary restricted to a trinity: “sign up”, “sign in”, “sign out”

Beyond

Clearance does not try to be a Swiss Army knife but it does have some hooks if you want admin roles, sign up and sign in by username in addition to email, or something else.

Please report bugs and request features on GitHub Issues.

Written by .