On Aug 6, 2014, at 12:51 PM, [email protected] wrote:
[snip]
>  
> Why does that matter?
> It matters because it is possible for a developer to accidentally lose that
> capability accidentally very easily on the way from the controller (where
> permit happened and the capability gets created) to the model (where the
> capability gets used). This loss does happen silently and effectively disables
> mass assignment protection.
> 
> How does that happen?
> The only class aware of the 'permitted?' capability is
> ActiveController::Parameters, if we call a method that is not aware of the
> capability it can get lost as a side effect:
> 
> class SomeModel < ActiveRecord::Base
>   #fields :name, :protected_secret_field
>   include ActiveModel::ForbiddenAttributesProtection
> end
> 
> #imagine a request w/ params = {'name' => 1, 'protected_secret_field' => 2}:
> params.reject!{|k,_|['controller', 'action'].include? k}
> params.permit(:name)
> SomeModel.new(params) #Exception, world is OK
> SomeModel.new(params.symbolize_keys) #No Exception, secret overwritten
> 

This is a bug in `symbolize_keys`. It appears to have been fixed (accidentally? 
on purpose?) on master:

https://github.com/rails/rails/commit/f1bad130d0c9bd77c94e43b696adca56c46a66aa

by starting the loop with `self.class.new` instead of `{}`.

There’s some additional future changes coming up in Ruby 2.2.0 with methods 
like `reject`:

https://www.ruby-lang.org/en/news/2014/03/10/regression-of-hash-reject-in-ruby-2-1-1/

that seem likely to further complicate the situation.

—Matt Jones

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

Reply via email to