views:

81

answers:

4

In my app, I have a "User" model, which includes a number of attributes including "has_admin_rights". If true, the user is an admin, if false, they aren't.

Each user has a profile, with their login name, email address, profile pic, etc.

If I'm logged in as a regular user, I can click on a page called "profile", and I can edit my own account, e.g. updating my email address, profile pic, password, whatever. I can ONLY edit my account, and no other.

If I'm logged in as an admin, I can do a little more: for example, I can make ANOTHER user an admin, or take away their admin rights.

Now, only an admin has access to the view where the "make admin" check box appears, but I have a feeling that simply restricting access to the view isn't sufficient.

What I'm concerned about is, since any user can edit their own profile, what's there to stop a user from submitting a custom form post, which has in it the "has_admin_rights"=>"1" parameter on their own account - thereby granting themselves admin access?

What I'm thinking is that, in the User controller, before applying any changes to the "has_admin_rights" field, that I need to check to make sure the user making the request is currently an admin - otherwise I ignore the request altogether, and make no changes.

+2  A: 

in the User controller, before applying any changes to the "has_admin_rights" field, that I need to check to make sure the user making the request is currently an admin - otherwise I ignore the request altogether, and make no changes.

yes, exactly. Never trust the client; remember that anybody can just tweak the page directly with Firebug or whatever.

I'd also suggest that you consider adding an audit trail, and log something whenever one admin makes another user into an admin. Maybe also send email to all the admins for a particular group to let them know that an admin has been created (or that rights have been revoked).

Pointy
Perfect, thank you.
normalocity
So, in addition to your recommendations, I've decided to create an "admin_activity" table that will track all admin actions, changes, deletions, etc., even if it's not user-related.For certain actions (like user changes) it will also trigger an email alert - perfect idea.
normalocity
Thanks! Good luck. You really appreciate audit logging when the phone rings and there's an angry person on the other end who swears "But I haven't touched that page in months!"
Pointy
Just wanted to say thanks again. I've (1) added the auditing of admin actions, (2) successfully blocked the change of admin access by non-admin users, and (3) added a functional test to my test suite to make sure I never have this problem.Cheers!
normalocity
Glad to hear it - security is a scary topic and it's best to be fairly paranoid!
Pointy
A: 

Add a before_save in your User model that performs this validation .

NM
Well the trick there is that you also need to know what the state of the flag was *before* the action modified the User object. Maybe you can check for a "changed" state on objects in Rails; I don't know.
Pointy
A: 

Ue attr_accessible which white list of model attributes that can be set via mass-assignment

  class User < ActiveRecord::Base
    attr_accessible :has_admin_rights
  end

& in controller

  @user.has_admin_rights = current_user.is_admin? "1" : "0"
Salil
Salil, the `attr_protected` blacklist might be a better option. He wouldn't want to modify an `attr_accessible` whitelist each time he adds a User attribute.
macek
+1  A: 

attr_protected is pretty useful, too

class User < ActiveRecord::Base

  attr_protected :is_admin

end
macek