A user with administrateUsers permissions can activate a deactivated administrator account.
This requires a control panel user account with administrateUsers permissions.
$this->userActionChecks();
$this->requirePermission('administrateUsers'); // 1079
$userId = $this->request->getRequiredBodyParam('userId'); // 1082
$user = Craft::$app->getUsers()->getUserById($userId); // 1083
Craft::$app->getUsers()->activateUser($user); // 1090 — no admin guard
The mirror action actionDeactivateUser (2199-2200) explicitly does if ($user->admin) $this->requireAdmin(false);. actionActivateUser does not.
A non-admin with administrateUsers can activate a pending/inactive admin account. When combined with activating and then resetting an admin’s password, or resurrecting a deliberately deactivated admin, this creates a privilege gap and breaks the symmetry between deliberate activation and deactivation.
Data flow
POST users/activate-user, userId=<admin id>.
- Guard:
administrateUsers (non-admin grantable). No admin-target check.
- Sink:
activateUser($user) activates the admin account.
Report ID: 1569
A user with
administrateUserspermissions can activate a deactivated administrator account.This requires a control panel user account with
administrateUserspermissions.The mirror action
actionDeactivateUser(2199-2200) explicitly doesif ($user->admin) $this->requireAdmin(false);.actionActivateUserdoes not.A non-admin with
administrateUserscan activate a pending/inactive admin account. When combined with activating and then resetting an admin’s password, or resurrecting a deliberately deactivated admin, this creates a privilege gap and breaks the symmetry between deliberate activation and deactivation.Data flow
POST users/activate-user,userId=<admin id>.administrateUsers(non-admin grantable). No admin-target check.activateUser($user)activates the admin account.Report ID: 1569