For multi-tenant applications you should remember to scope associations.

Here’s an example to highlight potential scoping issues. Let’s consider the following simple domain model:

class Account < ApplicationRecord
  has_many :categories
  has_many :posts
  # Defines an account (tenant).
  # ...
end

class Category < ApplicationRecord
  belongs_to :account
  # An account has a predefined set of categories each post can have.
end

class Post < ApplicationRecord
  belongs_to :account
  belongs_to :author, class_name: "User"
  belongs_to :category
  # ...
end

When a user has to create post we will need to let the user choose the category from current_account.categories - but it can easily be forgotten that the submitted field post[category_id] should also be whitelisted at the model-level.

This problem can be solved in multiple ways.

1) Controller-level whitelisting

class PostsController < ApplicationController
  def create
    @post = current_account.posts.new(post_params)
    @post.category = current_account.categories.find(@post.category_id) if @post.category_id

    if @post.save
      redirect_to root_url
    else
      render :new
    end
  end

  private

  def post_params
    params.fetch(:post, {}).permit(
      :title,
      # + some other fields
      :category_id,
    )
  end
end

2) Model-level whitelisting

The cleaner approach would be to move the white-listing to the model.

class Post < ApplicationRecord
  before_validation :whitelist_category!

  # ...

  private

  def whitelist_category!
    self.category =
      if account && category_id
        account.categories.find(category_id)
      end
  end
end

Damage?

This vulnerability could in this specific example lead to one account showing the posts of another account if the posts are looked up via the category which is not a totally unreasonable thing you would do.

Conclusion

No matter the approach, we should remember to do this type of whitelisting when we let users set-up associations.