On Fri, May 22, 2009 at 11:42 PM, cainlevy <cainl...@gmail.com> wrote: > We're all familiar with attr_accessible and attr_protected. These methods > provide rudimentary support from malicious mass assignment ... when people > remember to use them. I usually remember to set them myself, except that I > really wouldn't be surprised if someone auditing my code found one or two > spots that I've forgotten. But this isn't about just changing the default to > a hardcore blacklist instead of an all-encompassing whitelist. This is about > when attr_accessible and attr_protected aren't enough. > > They're not enough when user roles enter into the picture. Just to take the > simplest possible example, let's suppose that an application has normal > registered users and it has staff. The staff, very trustable sorts (crossed > fingers), are allowed to change attributes that normal users are not. It's a > problem that attr_accessible and attr_protected, being very static lists, > are not prepared to handle. But let's not stop there. We've all coded spots > where we wanted to directly assign a couple of attributes ourselves to > trusted values, but we couldn't use mass assignment because we (the devs) > have essentially told the code to not even trust ourselves.
I completely agree with you. Which attributes are allowed to be mass-assigned is almost always context-sensitive, and thus the whitelist doesn't belong in the class level. > And yet ... it's such a pretty syntax. Who wants to give that up? > > I do! Well, just a little. > > My idea (most likely not original) is to let the controller specify which > attributes may be assigned. In its briefest form, my proposal is be to > remove attr_accessible/attr_protected and change the mass assignment API as > follows: > > * User.new(params[:user]) becomes User.new(params[:user], whitelist) > * @user.attributes = params[:user] becomes @user.assign(params[:user], > whitelist) Agreed. How about a simple extension to Hash (somebody let me know if this exists already) that allows you to do: user.attributes = params[:user].pick(:first_name, :last_name) (Naive implementation here: http://gist.github.com/116880) The RHS could be extracted to a separate method in the relevant controller, which would do the context checking. Regardless of the syntax I think the use of attr_accessible at the class level should not be encouraged. I'm +1 on this. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---