A blog about software by Alexander YaƤkov Garber.

Mass Assignment

Security Flaw of Mass Assignment

# Valid
@user.update_attributes({username: 'kskoglund'})

# Hacked
@user.update_attributes({username: '733thax0r', password: 'nososecretanymore', admin: true})

Failing Code (ActiveModel::ForbiddenAttributesError)

def create
    # Instantiate a new object using form parameters.
    @subject = Subject.new(params[:subject])
    params.permit

    # Save the object.
    if @subject.save
    # If save succeeds, redirect to index action.
    redirect_to(subjects_path)
    else
    # If save fails, redisplay the form.
    render('new')
    end
end

Strong Parameters, i.e. Whitelisting

#permit:

Returns a new ActionController::Parameters instance that includes only the given filters and sets the permitted attribute for the object to true. This is useful for limiting which attributes should be allowed for mass updating.

params = ActionController::Parameters.new(user: { name: "Francesco", age: 22, role: "admin" })
permitted = params.require(:user).permit(:name, :age)
permitted.permitted?      # => true
permitted.has_key?(:name) # => true
permitted.has_key?(:age)  # => true
permitted.has_key?(:role) # => false

#require

ActionController::Parameters.new(person: { name: "Francesco" }).require(:person)
# => <ActionController::Parameters {"name"=>"Francesco"} permitted: false>

Example

params[:user] = { name: 'John Smith', email: 'john.smith@me.com', admin: false }

@user = User.new(params[:user])
permitted = params[:user].require(:email).permit(:name)

Passing Code

class SubjectsController < ApplicationController

    def create
        @subject = Subject.new(subject_params)

        if @subject.save
            redirect_to(subjects_path)
        else
            render('new')
        end
    end

    private

    def subject_params
        params.require(:subject).permit(:name, :position, :visible)
    end
end