update wp_dropdown_roles() with a filter to limit displayed rolenames (security)
|Reported by:||jeremyclarke||Owned by:||jeremyclarke|
|Severity:||normal||Keywords:||has-patch capabilities needs-testing|
For history see: #6014
I'm updating that patch so it can be added to 2.8, but i'm splitting up the various parts so they can be added more easily.
Part 1 was #8760, now commited.
What I want (same as #8760): To add security to the capabilities system because right now edit_users can't be delegated to non-admins (in our case our content editors). If someone has 'edit_users' they can make themself admin because nothing stops them from editing themselves or others to be admin. I think it should be integrated into core but don't care enough to fight. It can be done with a plugin so my priority is to make sure that my plugin (and Role Manager plugin) can hook into the appropriate places and add a role comparison such that wp only lets people edit users/roles "lower" than them (i.e. users that don't have any powers that the editor don't have).
This specific patch is to allow plugins to control the list of roles used in dropdown menus. The menus i'm talking about are displayed at the top of the users.php user list, as well as in the edit-user.php user editing page (i will write a patch to make that happen, user-edit.php is currently duplicating the logic already present in wp_dropdown_roles). They have a list of all roles and you choose a new role and save (on users.php you do this by checking the checkbox next to a user, changing hte role dropdown, then saving).
Currently, these menus just show every role available on the site, with the result that an 'Editor', if given the 'edit_users' privilege, is able to check the box next to their name, select 'administrator' from the dropdown then save, giving them administrator privileges.
The main change in the patch is to add_filter('role_names_listing', $role_names), giving plugins a chance to remove undesirable/innapropriate entries from the list. This allows my plugin code to assess which roles the current logged-in user should be able to edit, and hide the others so they can't be used. In conjunction with hiding checkboxes for other users they aren't allowed to edit, this will remove the ability of malicious users to promote themselves above their current level.
I also added some phpdoc for this function, feedback about that welcome. I also changed the label for the parameter $default to be called $selected, as it defines which element in the list will be selected initially and $default is a bit too generic for my taste.
Feedback about the patch welcome.
The plugin code to make this work can be found here: http://www.pastie.org/349208
Note that to see my patch in action you will need to run that plugin code as well as have a non-admin user with the edit_users cap (install and use Role Manager plugin to do that). Log in as the non-admin with edit_users and go to the user listing page, you'll notice that 'administrator' is no longer on the dropdown list.