Do not create records directly from form parameters

The scaffold generator creates code like the following, which is allowedly easier to handle, but vulnerable:

@user = User.new(params[:user])

With this code, Rails will create a new user based on the values that the user entered. Any corresponding attributes in the parameter hash params will be set in the user model. Arbitrary properties of the new user can be set by an attacker, the user's privileges, for example. Given you have a user registration form like this:

<form method="post" action="http://www.website.domain/user/register">
  <input type="text" name="user[name]" />
  …
</form>

An attacker could change the form (by saving it to disk, for example) to the following:

<form method="post" action="http://www.website.domain/user/register">
  <input type="text" name="user[name]" />
  <input type="text" name="user[admin]" value="1" />
  …
</form>

 
If the attacker knows that the User model has an “admin” column, the newly created user will have administrator rights. One solution to this problem is, not to use mass-assignment and assign each value individually.

User.new(:first_name => params[:user][:first_name])

Another solution is, to protect several properties so they can't be assigned using mass-assignment, but have to be set individually. The following line in your model will protect the “admin” attribute, i.e. it will be ignored during mass-assignment.

attr_protected :admin

If you want to set a protected attribute, you will to have to assign it individually:

@user = User.new(params[:user])
@user.admin = false
 

You can also use the whitelist approach (highly recommended), which allows attributes to be mass-assigned, instead of forbidding access to them. Use attr_accessible with the attributes you want to allow access to, instead of attr_protected to do this.