phpMyFAQ has stored XSS via Utils::parseUrl() in comment rendering
Date: 2026-05
Affected: composer/phpmyfaq/phpmyfaq, composer/thorsten/phpmyfaq
Attack vector: xss
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2026-46367
CWE: CWE-116
CWE-79
CVSS: 7.6 (CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:L/A:N)

### Summary A stored XSS vulnerability in the comment rendering pipeline allows an authenticated user to inject JavaScript that executes for every visitor of an affected FAQ or News page. An attacker with a registered account can steal admin session cookies and take over the application. ### Details `Utils::parseUrl()` (`phpmyfaq/src/phpMyFAQ/Utils.php`, line 281) converts URLs in comment text into clickable `<a>` tags at render time: $pattern = '/(https?:\/\/[^\s]+)/i'; $replacement = '<a href="$1">$1</a>'; return preg_replace($pattern, $replacement, $string); The regex `[^\s]+` matches `"` and `<`, and the URL is inserted into the href attribute with no htmlspecialchars() call. A URL with a literal `"` closes the attribute early and allows injecting event handlers like onmouseover. This only reaches the sink when `main.enableCommentEditor` is enabled. In that path, comment text goes through `sanitizeHtmlComment()` instead of `FILTER_SANITIZE_SPECIAL_CHARS` — which encodes `"` — so the double-quote survives to storage. The comment is then passed through parseUrl() and rendered via `{{ comment.comment|raw }}` in `comment.macros.twig` (line 40), which disables Twig auto-escaping. The same sink exists in the admin comment panel (`admin/content/comments.twig`, lines 62 and 112), so admins viewing the panel are also affected. No Content-Security-Policy headers are set anywhere in the app. ### PoC Requirements: - main.enableCommentEditor = true (set in admin


Mitigations:

Architectural layers (MAESTRO):