Advanced Rails - Building Industrial-Strength Web Apps in Record Time

(Tuis.) #1

132 | Chapter 5: Security


statement is bypassed. When we get to the part of the code that contains the secret,
$user_idis still 4 , and the secret is revealed even though the user was never success-
fully authenticated.


This design leads to huge security problems because the user has the potential to
choose the value of any local variable that you do not explicitly set. Fortunately for
all, theregister_globalsoption in PHP has been disabled for some time now by
default.


Form processing


We have a similar problem in Rails due to a compromise between security and brev-
ity of code. Rails supports mass assignment of form parameters to ActiveRecord
objects, so that form fields named person[first_name],person[last_name], and
person[email]can be used to build an ActiveRecordPersonobject with one line of
code:


person = Person.new params[:person]

Theparams[:person]object is a hash mapping attribute names to values, translated
from the form parameters courtesy of ActionController:


{:first_name => "John", :last_name => "Smith", :email => "[email protected]"}

Those parameters are assigned to thePersonobject, calling thePerson#first_name=,
Person#last_name=, andPerson#email=setters, respectively. It is just as if we had set
them individually:


person = Person.new
person.first_name = params[:person][:first_name]
person.last_name = params[:person][:last_name]
person.email = params[:person][:email]

This is a handy shortcut, but it leaves us vulnerable. Suppose someone submits the
form with a field namedperson[access_level]. Remember, the values that they sub-
mit need have no relation to the form we send them. By default, this would call
Person#access_level=with the value provided in the form. Clearly, we need to pro-
tect against this. We can either use theattr_protectedorattr_accessibleclass
methods of ActiveRecord::Base. The attr_protected method specifies which
attributes may not be assigned to via mass assignment:


class Person < ActiveRecord::Base
attr_protected :access_level
end

Conversely, theattr_accessiblemethod specifies which attributes may be assigned
to with mass assignment; any attributes not on the list are blocked. This is prefera-
ble when the list of attributes may change, as it represents a “default deny” stance. If
new attributes are added to the model, they will be blocked by default.


class Person < ActiveRecord::Base
attr_accessible :first_name, :last_name, :email
end
Free download pdf