Maybe I am grasping the full usage of this protect_from_forgery function, but it does not seem to work for me. Imagine the following: A simple website with a user that needs to log in to do certain stuff and a closed off admin section that only certain users can access that have the is_admin field set to true. So to be clear, my User model has a login, password and is_admin. When displaying the user''s ''profile'', he can only edit his password. I dont want him editing his own login or ofcourse is_admin status for obvious reasons. Now when I use firebug and inspect the page, I see a neat little field containing the authenticity_token. But here it comes, When I edit the page in firebug, and add a field called user_is_admin and set its value to 1, and then submit, the changes actually go through!! I have now made myself and admin. Isnt protect_from_forgery supposed to protect from this? Obviously in the controller I have kept it simple and did a @user.update_attributes(params[:user]), expecting that the authenticity_token would never allow any params to be posted that I didnt allow through my form. Did I do something wrong implementing this whole thing? I use the default cookie session store and still have the :secret key commented out, like how the project is generated. This is with rails 2.3.2 -- Posted via http://www.ruby-forum.com/.
Frederick Cheung
2009-Jun-09 21:39 UTC
Re: protect_from_forgery doesnt protect from forgery
> Now when I use firebug and inspect the page, I see a neat little field > containing the authenticity_token. > > But here it comes, > > When I edit the page in firebug, and add a field called user_is_admin > and set its value to 1, and then submit, the changes actually go > through!! I have now made myself and admin. > > Isnt protect_from_forgery supposed to protect from this? Obviously in > the controller I have kept it simple and did a > @user.update_attributes(params[:user]), expecting that the > authenticity_token would never allow any params to be posted that I > didnt allow through my form.The forgery protect_from_forgery protects against is cross site request forgery, ie. completely unrelated to the problem you''re tackling. You may be interested in attr_protected/attr_accessible. Fred> > Did I do something wrong implementing this whole thing? I use the > default cookie session store and still have the :secret key commented > out, like how the project is generated. > > This is with rails 2.3.2 > -- > Posted viahttp://www.ruby-forum.com/.
Frederick Cheung wrote:>> the controller I have kept it simple and did a >> @user.update_attributes(params[:user]), expecting that the >> authenticity_token would never allow any params to be posted that I >> didnt allow through my form. > > The forgery protect_from_forgery protects against is cross site > request forgery, ie. completely unrelated to the problem you''re > tackling. You may be interested in attr_protected/attr_accessible. > > FredAlright that makes sense. I might have misunderstood the PFF function. But I still feel this is a grossly underestimated security hole. It doesn''t seem very ruby-esque to shield the ''forbidden'' attributes with attr_accessors. Since on one form you might be allowed to change it, yet on a different one you wont have that field supplied. You obviously dont want to hard code your data entry restrictions on controller level. That violates the DRY principle. When I change the form to allow someone to edit an extra field, I also have to ''open up'' this field in the controller. The form fields I specify in the form are the only fields the user is allowed to change on that particular entry point. How can I enforce that no extra fields are introduced? I am thinking about an idea very similar to the authenticity token from protect_from_forgery. Create a hash based on all the fields in a form and some serverside secret. Whenever the post params come in I know which fields are posted so I can recreate this hash and compare. Has this been done before? Or would I have to build this into a plugin from scratch? -- Posted via http://www.ruby-forum.com/.
On Thu, Jun 11, 2009 at 4:20 PM, C, D.<rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:>>> the controller I have kept it simple and did a >>> @user.update_attributes(params[:user]), expecting that the >>> authenticity_token would never allow any params to be posted that I >>> didnt allow through my form. >> >> The forgery protect_from_forgery protects against is cross site >> request forgery, ie. completely unrelated to the problem you''re >> tackling. You may be interested in attr_protected/attr_accessible. >> >> Fred > > Alright that makes sense. I might have misunderstood the PFF function. > > But I still feel this is a grossly underestimated security hole. It > doesn''t seem very ruby-esque to shield the ''forbidden'' attributes with > attr_accessors. Since on one form you might be allowed to change it, yet > on a different one you wont have that field supplied. > > You obviously dont want to hard code your data entry restrictions on > controller level. That violates the DRY principle. When I change the > form to allow someone to edit an extra field, I also have to ''open up'' > this field in the controller.The current solution is a trade-off: it is a simple solution that covers most use cases. Often the account_id of your User model is protected, period. That''s what the current design supports. There was a recent discussion in the core mailing list about possible ways to make this a little more flexible: http://groups.google.co.uk/group/rubyonrails-core/browse_thread/thread/3b6818496d0d07f1/0d20bb9236fe59af#0d20bb9236fe59af but no conclusion except for some workarounds to the current solution when you need them.
Reasonably Related Threads
- [HELP]No :secret given to the #protect_from_forgery call
- protect_from_forgery development mode
- Rails noob confusion - HTML Form Post to Rails Controller?
- form_tag and form_for cause #protect_from_forgery errors
- protect_from_forgery with db-session (Rails 2.3.2)