Active Modelの「マスアサインメント(mass-assignment)によって制限なく変更できてしまう
4.6 Strong Parameters
strong parametersは、Action ControllerのパラメータをActive Modelの「マスアサインメント(mass-assignment)」で利用することを禁止
します(許可されたパラメータは除く)。したがって、開発者は、どの属性でマスアップデートを許可するかをコントローラで明示的に指定しなければなりません
。strong parametersは、Pユーザーがモデルの重要な属性を誤って更新してしまうことを防止`するための、より優れたセキュリティ対策です。
さらに、パラメータの属性をrequireにすると、
渡された必須パラメータが不足している場合に、事前定義済みのraise/rescueフローで「400 Bad Request」で終了できる
ようになります。
rails3.2.9の説明です
マスアサインメントとは?
無条件でModel.new(params[:model])
は攻撃者に攻撃者にデータベースのカラムの値を設定することを許す
— Without any precautions Model.new(params[:model]) allows attackers to set any database column’s value.
マスアサインメント脆弱性はマスアサインメントは攻撃者にmodel’s new() method
は渡されたハッシュを操ることによってモデルのいくつかの属性を設定するような問題をになるかもしれない。
The mass-assignment feature may become a problem, as it allows an attacker to set any model’s attributes by manipulating the hash passed to a model’s new() method:
def signup
params[:user] # => {:name => “ow3ned”, :admin => true}
@user = User.new(params[:user])
end
Mass-assignmentはたくさんの仕事を保存している。それは各々それぞれの値を保存してはいけない。単に新たなメソッドまたはassign_attributes= ハッシュ値
を渡すだけでハッシュの中の値へモデルの属性を設定することができます。その問題はコントローラで使用可能なパラメータハッシュと組み合わせて使われることが多く、攻撃者による操作されるかもしれない。彼はこのようにURLを変更することによってそのようになる可能性がある。
Mass-assignment saves you much work, because you don’t have to set each value individually. Simply pass a hash to the new method, or assign_attributes= a hash value, to set the model’s attributes to the values in the hash. The problem is that it is often used in conjunction with the parameters (params) hash available in the controller, which may be manipulated by an attacker. He
may do so by changing the URL like this:
http://www.example.com/user/signup?user[name]=ow3ned&user[admin]=1
コントローラ内で以下のパラメータで設定される
This will set the following parameters in the controller:
params[:user] # => {:name => “ow3ned”, :admin => true}
だからもしマスアセスメントを使って新たなユーザーを作るならば、多分管理者になることはとても簡単すぎる。
So if you create a new user using mass-assignment, it may be too easy to become an administrator.
これの脆弱性はデータベースカラムへ限定されていないことに注意してください。明確に防御できなければどんなセッターメソッドは、attributes= method
を通ってアクセス可能だ。事実、脆弱性は Rails 2.3で(入れ子のオブジェクトフォームと)入れ子のミスアセスメントを紹介でさらにもっと拡張される。accepts_nested_attributes_for
宣言はモデルの連想(has_many, has_one, has_and_belongs_to_many+)へマスアサインメントを広げるための能力を供給する
Note that this vulnerability is not restricted to database columns. Any setter method, unless explicitly protected, is accessible via the attributes= method. In fact, this vulnerability is extended even further with the introduction of nested mass assignment (and nested object forms) in Rails 2.3. The accepts_nested_attributes_for declaration provides us the ability to extend mass assignment to model associations (has_many, has_one, has_and_belongs_to_many+). For example:
class Person < ActiveRecord::Base
has_many :children
accepts_nested_attributes_for :children
end
class Child < ActiveRecord::Base
belongs_to :person
end
accepts_nested_attributes_forは現在も使えるそう
class Member < ActiveRecord::Base
has_one :avatar
accepts_nested_attributes_for :avatar
end
params = { member: { name: 'Jack', avatar_attributes: { icon: 'smiling' } } }
member = Member.create(params[:member])
member.avatar.id # => 2
member.avatar.icon # => 'smiling'
感想
-
[admin]=1
とは - マスアサインメントは制限をかけないと簡単にデータを操作することができるから制限をかけるストロングパラメータが必要だとわかった。