phpMyFAQ has Stored XSS in user list via admin-managed display_name
Date: 2025-12
Affected: composer/thorsten/phpmyfaq
Attack vector: xss
Category: vulnerability-disclosure
Severity: Medium
CVE: CVE-2025-68951
CWE: CWE-79
CVSS: 5.4 (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N)

### Summary A stored cross-site scripting (XSS) vulnerability allows an attacker to execute arbitrary JavaScript in an administrator’s browser by registering a user whose **display name** contains HTML entities (e.g., `&lt;img ...&gt;`). When an administrator views the admin user list, the payload is decoded server-side and rendered without escaping, resulting in script execution in the admin context. ### Details Root cause is the following chain: - **User-controlled input stored**: attacker-provided `display_name` (real name) is stored in DB (often as HTML entities, e.g., `&lt;img ...&gt;`). - **Decode on read**: `phpmyfaq/src/phpMyFAQ/User/UserData.php` decodes `display_name` using `html_entity_decode(...)` (“for backward compatibility”). - **Unsafe sink**: admin user list renders the decoded value unescaped using Twig `|raw`: - `phpmyfaq/assets/templates/admin/user/users.twig` (users table uses `{{ user.display_name|raw }}`) As a result, an entity-encoded payload becomes active HTML/JS when rendered in the admin user list. Note: This report is about the `display_name` field + entity-decoding path. It is distinct from previously published issues focused on the `email` field. ### PoC (minimal reproduction) **Preconditions / configuration** - Registration enabled (`security.enableRegistration = true`). - Attacker does not need admin privileges. - Admin must view the admin user list page. **Steps** 1. As an unauthenticated user, open the registration page and create a n


Mitigations:

Architectural layers (MAESTRO):