A AegiFlow
HIGHCVSS 8.8

GHSA-pg62-f8g4-4wqh

phpMyFAQ privilege escalation: GroupController::updatePermissions lets a GROUP_EDIT admin grant rights they do not hold

Published
2026-08-25
Modified
2026-08-25
Sources
github-advisory

Summary

## Overview When phpMyFAQ hardened its admin permission-assignment endpoints against privilege escalation, it added a "a non-SuperAdmin may only assign rights they themselves hold" constraint to the user-rights endpoint (`UserController::updateUserRights`). **The equivalent group-rights endpoint, `GroupController::updatePermissions`, did not receive that constraint.** A delegated administrator holding only the `GROUP_EDIT` permission can therefore grant any group an arbitrary set of rights — including rights the administrator does not possess — and, by being (or becoming) a member of that group, inherit those rights, escalating to higher privileges up to full administrative control. ## Impact phpMyFAQ supports delegated administration: the `GROUP_EDIT` right can be granted to a non-SuperAdmin so they can manage groups. Such an administrator can escalate: 1. They call `POST /admin/group/update/permissions` with `group_id` set to a group they belong to (or can manage membership of) and `group_rights[]` containing high-value rights they do **not** themselves hold (e.g. user administration, or any right gating sensitive actions). 2. The endpoint grants every requested right to the group with no check that the caller holds them. 3. Members of that group — including the attacker — inherit the granted rights, escalating the attacker's effective privileges. This is the group-side mirror of exactly what the maintainers blocked on the user-rights side, where the code comment names the threat explicitly ("prevents an administrator with the delegable USER_EDIT right from granting privileges they do not possess (privilege escalation)"). The group path remains open. `PR:L` (the attacker needs the delegable `GROUP_EDIT` right, below SuperAdmin), `S:U` (escalation within phpMyFAQ's single authorization authority), `C:H/I:H/A:H` (inherited rights can reach full administrative read/write/availability control). The one added step versus the user-rights path — the attacker must be a member of the group they elevate (a GROUP_EDIT admin generally manages group membership, hence `AC:L`) — is noted in Technical Details. ## Technical Details References are to `phpmyfaq/src/phpMyFAQ/` at HEAD `04db2b999d8d`. **The vulnerable endpoint — no self-rights check (`Controller/Administration/GroupController.php:309-349`):** ```php #[Route(path: '/group/update/permissions', name: 'admin.group.update.permissions', methods: ['POST'])] public function updatePermissions(Request $request): Response { $this->userHasPermission(PermissionType::GROUP_EDIT); // only requires GROUP_EDIT — not SuperAdmin, no per-right check // ... CSRF verified ... $groupId = (int) Filter::filterVar($request->request->get('group_id'), FILTER_VALIDATE_INT); $groupPermissions = $request->request->all()['group_rights']; // attacker-controlled list of right IDs $refuseResult = $this->user->perm->refuseAllGroupRights($groupId); if ($refuseResult) { foreach ($groupPermissions as $groupPermission) { $this->user->perm->grantGroupRight($groupId, (int) $groupPermission); // grants ANY right, unconstrained } ... } } ``` Each `group_rights[]` entry is granted to the group verbatim; there is no verification that the acting administrator holds that right. **The fixed sibling — `updateUserRights` DOES constrain to self-held rights (`Controller/Administration/Api/UserController.php:558-579`):** ```php $actingIsSuperAdmin = $this->currentUser->isSuperAdmin(); // A non-SuperAdmin may only assign rights they hold themselves. This prevents an // administrator with the delegable USER_EDIT right from granting privileges they do not // possess (privilege escalation). if (!$actingIsSuperAdmin) { $actingUserId = $this->currentUser->getUserId(); foreach ($userRights as $userRight) { if (!$this->currentUser->perm->hasPermission($actingUserId, (int) $userRight)) { return $this->json(['error' => Translatio

Affected packages

EcosystemPackageAffected versionsFixed versions
Packagistphpmyfaq/phpmyfaq4.1.5
Packagistthorsten/phpmyfaq4.1.5

Remediation: Upgrade to 4.1.5 or later.

References

Includes data from the GitHub Advisory Database, licensed under CC-BY 4.0.