GHSA-985r-q3qp-299h: phpMyFAQ has an incomplete fix for GHSA-xvp4-phqj-cjr3 — editUser() and updateUserRights() lack authorization guards
phpMyFAQ 4.1.3 fixed GHSA-xvp4-phqj-cjr3 (“IDOR Account Takeover”) by adding actor-authorization guards to UserController::overwritePassword(). The patch establishes a new invariant, stated in its own code comments:
“Only SuperAdmins may change other users’ [attributes]. Self-service is always allowed.” and “a non-SuperAdmin must never be able to alter a SuperAdmin or protected account.”
That invariant is not enforced on two sibling endpoints in the same file, which the 4.1.3 fix left unchanged, and which carry the identical “user-controlled userId → getUserById() → privileged mutation” primitive — but with a strictly more dangerous sink:
| Endpoint | Route | Sink | Guard in 4.1.3 |
|---|---|---|---|
overwritePassword() | admin/api/user/overwrite-password | changePassword() | isSelf + isSuperAdmin + target-protection (patched) |
editUser() | admin/api/user/edit | setSuperAdmin((bool)$req.is_superadmin) | none (only userHasPermission(USER_EDIT)) |
updateUserRights() | admin/api/user/update-rights | grantUserRight($req.userId, …) | none (only userHasPermission(USER_EDIT)) |
A logged-in administrator holding the delegable edit_user right — but not SuperAdmin — can therefore:
- Set their own (or anyone’s)
is_superadminflag totrueviaadmin/api/user/edit→ full privilege escalation to SuperAdmin. - Grant arbitrary rights to any account via
admin/api/user/update-rights.
This is exactly the threat model the parent advisory (GHSA-xvp4) calls out: “organizations with multiple admin users where not all should have SuperAdmin access.”
References
Code Behaviors & Features
Detect and mitigate GHSA-985r-q3qp-299h with GitLab Dependency Scanning
Secure your software supply chain by verifying that all open source dependencies used in your projects contain no disclosed vulnerabilities. Learn more about Dependency Scanning →