Posted by Leonardo Fri, 03 Aug 2007 01:27:39 GMT
Mass assignment é uma ferramenta muito poderosa que o ActiveRecord nos fornece. Com ela, podemos criar um objeto, passando todas as informações de um formulário, simplesmente com uma linha de código. Mas, sem tomar as devidas precauções, podemos nos encrencar feio criando falhas de segurança na aplicação.
Vejamos um exemplo simples de como isso pode acontecer. Suponha que tenhamos esse migration:
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.column :name, :string
t.column :admin, :boolean
end
end
def self.down
drop_table :users
end
end
esse controller:
class UserController < ApplicationController
def create
@user = User.create(params[:user])
end
end
e esse view:
<form method="post" action="/user/create">
<input type="text" name="user[name]" />
</form>
Tudo pronto e funcionando. Até que de repente, alguém resolver brincar um pouco com os dados do formulário e submete um form com os seguintes dados:
<form method="post" action="/user/create">
<input type="text" name="user[name]" />
<input type="hidden" name="user[admin]" value="1" />
</form>
Pronto. O usuário agora também é um administrador e pode fazer coisas desastrosas.
Podemos resolver isso dizendo para o model quais são os campos protegidos e que serão ignorados pelo mass assignment.
class User < ActiveRecord::Base
attr_protected :admin
end
Outra forma de resolver o problema, é dizendo para o model quais são os campos permitidos para mass assignment.
class User < ActiveRecord::Base
attr_accessible :name
end
A diferença entre as duas abordagens é, que na primeira, os campos são permitidos por default e somente os campos listados são protegidos, enquanto que na segunda acontece justamente o contrário.
Particularmente, acho a segunda abordagem mais segura, porque, se criarmos mais campos posteriormente, eles estarão protegidos por default.
A seguir, falarei de SQL Injection.
