Happy Bear Software

You Should Be Whitelisting Parameters

In the rails world, the following is a common pattern:

# Blacklisted Request Parameters

class BlacklistingUsersController < ApplicationController
  def update
    user = User.find(params[:id])

The intention here is to delete the :admin parameter so that a user isn't able to switch this parameter to 'true' on their own account.

This is an example of blacklisting, or rejecting known bad. In general it's considered more effective to whitelist parameters i.e. accepting known good.

In all situations where you are intending to filter parameters, it is a great deal safer in the long run to whitelist parameters instead of blacklist. An example of how you might do this in a Rails controller might be:

# Whitelisted Request Parameters, as suggested by DHH

class WhitelistingUsersController < ApplicationController
  def update
    user = User.find(params[:id])
    user.update_attributes user_params


  def user_params
    params[:user].slice :first_name, :last_name, :email

Here we've specified exactly which parameters we intend to pass to update_attributes rather than used whatevers left after removing the :admin parameter.

Isn't attr_accessible enough?

No. The fundamental problem with relying on attr_accessible is that filtering request parameters is a controller concern. That's not to say there might be a neater way of expressing a parameter whitelist, but it really needs to be on a per-controller or even per-action basis, rather than set once globally for wherever the model is used.

Having a single, globally set list of whitelisted parameters for a given user model begins to make a lot less sense when you're manipulating your model from multiple parts of your system. Taking are users controller example further:

In both of the above cases, having a parameter whitelist at the controller level would go a long way towards preventing inadvertent security vulnerabilities.

More benefits of whitelisting over blacklisting

This has the following benefits over blacklisting: