Read more

Safely chain scopes with hash conditions

Henning Koch
April 01, 2011Software engineer at makandra GmbH

There is a nasty bug in all version of Rails 2 and some versions of Rails 3.x where two chained scopes with hash conditions on the same attribute would overwrite each other.

Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

This is a horrible security issue if you are using scopes to limit what a user may see or change Show archive.org snapshot .

Workaround

If you are using an affected Rails version and cannot switch to a fixed version, you can use this manual workaround.

Copy the attached initializer into your project. You can then use a new pseudo-scope chain_safely that guarantees that conditions in the current chain are not going to be overwritten by the next chain link.

Use this for cases where you use scopes to restrict access, and want to further filter this scope based on user input:

class ArticlesController < ApplicationController

  def index
    articles = visible_articles
    articles = articles.chain_safely.for_users(params[:user_id_filter]) if params[:user_id_filter]
  end

  private

  def visible_articles
    current_user.articles
  end

end

Note that if you want to chain multiple scopes safely, you need to insert a chain_safely between each two links in the chain:

visible_article.chain_safely.some_scope.chain_safely.some_other_scope
Posted by Henning Koch to makandra dev (2011-04-01 10:46)