Administer Users - the sledgehammer permission
Do you give out the Administer Users permission on your Drupal websites? Did you know it's just as dangerous as Administer Permissions, as dangerous as giving access to User 1?
Imagine: you're about to go live. The client calls up, he wants to create users for everyone in the office. Even though the client is not a 100% trusted user (since no-one is), there is an easy solution for this: Administer Users.
Indeed, unless you implement some contributed modules, this is THE solution provided by Drupal core... Wait, read on!
We've been doing Drupal for a while and we know the following from our Drupal security 101:
- Don't give access to user/1
- Don't give any PHP access, like PHP filters
- Don't give access to Administer Permissions
But Administer Users? We've never doubted it. After all, you can't assign roles with this permission, you'd be forgiven for assuming it's the recommended way to do it.
Administer Users = User 1
With Administer Users, your client can edit User 1 and change the password and email address. The client can then log in as User 1 and gain access to PHP execution (among other things) which would then allow them to hack the database, or even scan other Drupal installations on the server and hack other Drupal sites.
After consulting the Security Team, I added a page to the Drupal handbook about Untrusted PHP execution. So at least now this issue is acknowledged directly in the best practices section of the handbook (I hope the whitehouse.gov people review that!)
As for closing this loophole? This is a reported issue, in at least one place, but marked "won't fix" by Dries (albeit 4 years ago). So the issue has been present from at least Drupal 5 and still exists in Drupal 7.
Further investigation revealed some related issues: Prevent User 1 deletion is preventing an support annoyance, rather than closing a security hole. Add current password field to edit form is only for a user's own account. Neither of these issues are addressing the situation, although some comments you'll read there hint at it.
Although I'm still evaluating it, the most promising solution to this problem is User Protect.
Alternatively, Paranoia focusses on universally preventing PHP execution, successfully applied to core's PHP Filter module. The Drupal 5 version also protected User 1 editing, and I've offered a patch for Drupal 6.
Are there more? There are a few red herring modules in contrib, please be careful to understand the issue before posting modules that supposedly fix this problem!
Feature image from Roserick Chamber