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
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
Frederick C. 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 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?
On Thu, Jun 11, 2009 at 4:20 PM, C, D.[email protected]
wrote:
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.