We have quite some special behavior for uid #1. This tends to confuse the user, and will do so even more now we have an admin role in core. Do all the special cases we designed around uid #1 really make sense?
Problems with special casing uid 1
- People are confused whether they should be sharing credentials of this user (bad) or just using a user with the Administrator role.
- The lack of permission check on user 1 means that uid 1 can take actions on a site even if they do not have a role that grants them the permission. This makes it hard to completely disable unwanted features on a site unless you block uid 1 and never use it.
- The lack of permission check on user 1 makes them a particularly valuable account for an attacker to take over in some way. Any time there is a focus point for an attack it makes the system weaker.
Potential problems with *not* special casing
If someone is playing around and removes all roles or removes all permissions from all their admin users it could be possible to have no users with administrator permissions on a site. While is is a problem it is easily solved with a FAQ page and some database instructions just like we do with WSOD.
Also, because of the long legacy of this in core, both contrib modules and custom code in individual sites might (will, in some cases, see #175) have adopted similar code to grant uid=1 special privileges. When core no longer makes any assumptions about the specialness of uid=1, site maintainers may now strip uid=1 from its admin role, thinking it is now a normal user, only to have hard-coded god-funcitonality lingering around their site.
Proposed resolution
The special behaviour of uid 1 should be removed. Instead there is an admin role that always has all permissions. All special treatment for uid 1 should be converted to proper permissions, and as the admin role always has all permissions, any member of this role would have the same access as uid 1 has now. The following steps need to be taken:
- Create an admin role by default, just like the anonymous and authenticated role, in the user module, and also make it undeletable, and make it the admin role.
- Assign user 1 the admin role on install. (do this in the user module, not the chosen install profile).
- Document the steps to take in case you want to grant the admin role to a user when no-one has it. This should include instructions for drush, drupal console or for using a simple insert/update query.
- Create a change record and raise awareness. We want to make sure contrib modules are ready by 8.5.x so that their tests won't break all of the sudden or, god forbid, they have a security vulnerability. Modules can already adapt their code now because, in essence, nothing changes. We're just enforcing good practice of not relying on a god-mode user account in our code.
Remaining tasks
Create patch(see #169- Review patch
- Commit #2917584: Some tests only go green because they happen to run as UID1
- Turn scan for uid=1 in contrib into script (see #175)?
- Involve security team for modules found by script and/or #175
- Change record (work has started)
Create issue for Coder module(see #2975233: Add a sniff for checking against hard-coding uid=1 permissions)- Commit
- Appropriate amount of publicity about the change and make sure people understand the implications of removing the admin role from uid=1 and the risks involved with third-party code still assigning special privileges.
API changes
None. Just need to raise awareness that UID 1 no longer has an all-access pass.