CVE-2026-45007: phpMyFAQ's Missing CONFIGURATION_EDIT Permission Check on 12 Admin API Configuration Tab Endpoints Allows Information Disclosure by Any Authenticated User
Summary
12 endpoints in ConfigurationTabController.php use userIsAuthenticated() (login-only check) instead of userHasPermission(PermissionType::CONFIGURATIONEDIT). This allows any authenticated user — including ones with zero admin permissions — to enumerate system configuration metadata including the permission model, active template, cache backend, mail provider, and translation provider.
Details
The ConfigurationTabController contains 15 public endpoints. Three of them (list, save, uploadTheme) correctly enforce CONFIGURATIONEDIT permission:
php // phpmyfaq/src/phpMyFAQ/Controller/Administration/Api/ConfigurationTabController.php:63 public function list(Request $request): Response { $this->userHasPermission(PermissionType::CONFIGURATIONEDIT); // ✅ Correct // ... }
The remaining 12 only check that the user is logged in:
php // phpmyfaq/src/phpMyFAQ/Controller/Administration/Api/ConfigurationTabController.php:353 public function translations(): Response { $this->userIsAuthenticated(); // ❌ Missing permission check // ... }
The difference between these two methods is significant:
php // AbstractController.php:258 — login-only protected function userIsAuthenticated(): void { if (!$this->currentUser->isLoggedIn()) { throw new UnauthorizedHttpException(challenge: 'User is not authenticated.'); } }
// AbstractController.php:317 — login + permission check protected function userHasPermission(PermissionType $permissionType): void { if (!$this->currentUser->isLoggedIn()) { throw new UnauthorizedHttpException(challenge: 'User is not authenticated.'); } $currentUser = $this->currentUser; if (!$currentUser?->perm->hasPermission($currentUser->getUserId(), $permissionType->value)) { throw new ForbiddenException(/ ... /); } }
There is no middleware or router-level authorization — the Kernel (Kernel.php) dispatches directly to controllers with only Language, Router, and Exception listeners. All authorization is at the controller method level.
The 12 affected endpoints (all GET, all under /admin/api/):
| # | Method | Route | Info Exposed | |---|--------|-------|-------------| | 1 | translations() | /configuration/translations | Available languages + current language | | 2 | templates() | /configuration/templates | Available themes + active theme | | 3 | faqsSortingKey() | /configuration/faqs-sorting-key/{current} | FAQ sorting key options | | 4 | faqsSortingOrder() | /configuration/faqs-sorting-order/{current} | FAQ sorting order | | 5 | faqsSortingPopular() | /configuration/faqs-sorting-popular/{current} | Popular FAQ sorting | | 6 | permLevel() | /configuration/perm-level/{current} | Permission model (basic/medium) | | 7 | releaseEnvironment() | /configuration/release-environment/{current} | Dev/production environment | | 8 | searchRelevance() | /configuration/search-relevance/{current} | Search relevance config | | 9 | seoMetaTags() | /configuration/seo-metatags/{current} | SEO meta tag config | | 10 | translationProvider() | /configuration/translation-provider/{current} | Translation service (DeepL, etc.) | | 11 | mailProvider() | /configuration/mail-provider/{current} | Mail provider (SMTP, etc.) | | 12 | cacheAdapter() | /configuration/cache-adapter/{current} | Cache backend (filesystem/redis/memcached) |
The translations() and templates() endpoints directly read from config/filesystem and expose current settings. The {current} endpoints render HTML <option> dropdowns where the caller-supplied value gets the selected attribute — an attacker can enumerate possible values to discover the current configuration.
PoC
bash Step 1: Authenticate as any user (even one with no admin permissions) and obtain the session cookie (pmfauthXXXX)
Step 2: Query configuration endpoints that should require CONFIGURATIONEDIT permission
Enumerate available languages and current language setting curl -s -b 'pmfauthXXXX=<session>' \ https://target.example/admin/api/configuration/translations
Enumerate available templates and which is active curl -s -b 'pmfauthXXXX=<session>' \ https://target.example/admin/api/configuration/templates
Discover permission model by trying known values curl -s -b 'pmfauthXXXX=<session>' \ https://target.example/admin/api/configuration/perm-level/basic
Discover release environment curl -s -b 'pmfauthXXXX=<session>' \ https://target.example/admin/api/configuration/release-environment/development
Discover cache backend curl -s -b 'pmfauthXXXX=<session>' \ https://target.example/admin/api/configuration/cache-adapter/filesystem
Discover mail provider curl -s -b 'pmfauthXXXX=<session>' \ https://target.example/admin/api/configuration/mail-provider/smtp
Discover translation provider curl -s -b 'pmfauthXXXX=<session>' \ https://target.example/admin/api/configuration/translation-provider/deepl
Expected: HTTP 403 Forbidden for a user without configurationedit permission. Actual: HTTP 200 with configuration data in HTML option format.
Impact
Any authenticated user (e.g., a regular FAQ contributor or a user with minimal permissions) can enumerate:
- The instance's permission model (basic vs. medium) — reveals access control architecture - Whether the instance runs in development or production mode — development mode may expose debug info - The cache backend (filesystem/redis/memcached) — useful for targeting cache-specific attacks - The mail provider configuration — reveals infrastructure details - Available and active templates/themes — aids in targeting template-specific vulnerabilities - Translation provider (e.g., DeepL) — reveals third-party service integrations
While no credentials or secrets are directly exposed, this configuration metadata aids targeted follow-up attacks and violates the principle of least privilege — these endpoints exist to serve the admin configuration UI and should require the same CONFIGURATIONEDIT permission as the list and save endpoints.
Recommended Fix
Replace $this->userIsAuthenticated() with $this->userHasPermission(PermissionType::CONFIGURATIONEDIT) in all 12 affected methods:
php // In ConfigurationTabController.php — apply to all 12 methods // Before (line 355, and equivalent in all others): $this->userIsAuthenticated();
// After: $this->userHasPermission(PermissionType::CONFIGURATIONEDIT);
Affected methods: translations(), templates(), faqsSortingKey(), faqsSortingOrder(), faqsSortingPopular(), permLevel(), releaseEnvironment(), searchRelevance(), seoMetaTags(), translationProvider(), mailProvider(), cacheAdapter().
Other sources
phpMyFAQ before 4.1.2 contains missing permission checks in ConfigurationTabController.php where 12 endpoints use userIsAuthenticated() instead of userHasPermission(CONFIGURATIONEDIT). Any authenticated user can enumerate system configuration metadata including permission model, cache backend, mail provider, and translation provider by querying /admin/api/configuration endpoints, violating least privilege access control.
— MITRE
phpMyFAQ's Missing CONFIGURATIONEDIT Permission Check on 12 Admin API Configuration Tab Endpoints Allows Information Disclosure by Any Authenticated User
— Packagist
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
composer/phpmyfaq/phpmyfaqto a version that resolves this vulnerability.Fixed in 4.1.2 - Upgrade
Upgrade
composer/thorsten/phpmyfaqto a version that resolves this vulnerability.Fixed in 4.1.2 - Upgrade
Upgrade
phpMyFAQto a version that resolves this vulnerability.Fixed in 4.1.2
Event History
Frequently Asked Questions
What is the severity of CVE-2026-45007?
CVE-2026-45007 is classified as a medium severity vulnerability due to the potential for unauthorized information disclosure.
How do I fix CVE-2026-45007?
To fix CVE-2026-45007, upgrade phpMyFAQ to version 4.1.2 or higher where the missing permission checks have been addressed.
What kind of information is at risk due to CVE-2026-45007?
CVE-2026-45007 can lead to the disclosure of sensitive configuration information accessible to unauthenticated users.
Which software versions are affected by CVE-2026-45007?
CVE-2026-45007 affects phpMyFAQ versions prior to 4.1.2.
Is CVE-2026-45007 a coding error?
Yes, CVE-2026-45007 is due to a coding error where the application checks for user authentication instead of the necessary permissions.