Severity by source
AV:N/AC:L/PR:H/UI:R/S:U/C:H/I:H/A:N
Primary rating from GitHub Advisory · only source for this CVE.
CVSS VectorGitHub Advisory
CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:U/C:H/I:H/A:N
Lifecycle Timeline
4DescriptionGitHub Advisory
Summary
The sanitization pipeline for FAQ content is:
Filter::filterVar($input, FILTER_SANITIZE_SPECIAL_CHARS)- encodes<,>,",',&to HTML entitieshtml_entity_decode($input, ENT_QUOTES | ENT_HTML5)- decodes entities back to charactersFilter::removeAttributes($input)- removes dangerous HTML attributes
The removeAttributes() regex at line 174 only matches attributes with double-quoted values:
preg_match_all(pattern: '/[a-z]+=".+"/iU', subject: $html, matches: $attributes);This regex does NOT match:
- Attributes with single quotes:
onerror='alert(1)' - Attributes without quotes:
onerror=alert(1)
An attacker can bypass sanitization by submitting FAQ content with unquoted or single-quoted event handler attributes.
Details
Affected File: phpmyfaq/src/phpMyFAQ/Filter.php, line 174
Sanitization flow for FAQ question field:
FaqController::create() lines 110, 145-149:
$question = Filter::filterVar($data->question, FILTER_SANITIZE_SPECIAL_CHARS);
// ...
->setQuestion(Filter::removeAttributes(html_entity_decode(
(string) $question,
ENT_QUOTES | ENT_HTML5,
encoding: 'UTF-8',
)))Template rendering: faq.twig line 36:
<h2 class="mb-4 border-bottom">{{ question | raw }}</h2>How the bypass works:
- Attacker submits:
<img src=x onerror=alert(1)> - After
FILTER_SANITIZE_SPECIAL_CHARS:<img src=x onerror=alert(1)> - After
html_entity_decode():<img src=x onerror=alert(1)> preg_match_all('/[a-z]+=".+"/iU', ...)runs:
- The regex requires
="..."(double quotes) onerror=alert(1)has NO quotes → NOT matchedsrc=xhas NO quotes → NOT matched- No attributes are found for removal
- Output:
<img src=x onerror=alert(1)>(XSS payload intact) - Template renders with
|raw: JavaScript executes in browser
Why double-quoted attributes are (partially) protected:
For <img src="x" onerror="alert(1)">:
- The regex matches both
src="x"andonerror="alert(1)" srcis in$keep→ preservedonerroris NOT in$keep→ removed viastr_replace()- Output:
<img src="x">(safe)
But this protection breaks with single quotes or no quotes.
PoC
Step 1: Create FAQ with XSS payload (requires authenticated admin):
curl -X POST 'https://target.example.com/admin/api/faq/create' \
-H 'Content-Type: application/json' \
-H 'Cookie: PHPSESSID=admin_session' \
-d '{
"data": {
"pmf-csrf-token": "valid_csrf_token",
"question": "<img src=x onerror=alert(document.cookie)>",
"answer": "Test answer",
"lang": "en",
"categories[]": 1,
"active": "yes",
"tags": "test",
"keywords": "test",
"author": "test",
"email": "test@test.com"
}
}'Step 2: XSS triggers on public FAQ page
Any user (including unauthenticated visitors) viewing the FAQ page triggers the XSS:
https://target.example.com/content/{categoryId}/{faqId}/{lang}/{slug}.htmlThe FAQ title is rendered with |raw in faq.twig line 36 without HtmlSanitizer processing (the processQuestion() method in FaqDisplayService only applies search highlighting, not cleanUpContent()).
Alternative payloads:
<img/src=x onerror=alert(1)>
<svg onload=alert(1)>
<details open ontoggle=alert(1)>Impact
- Public XSS: The XSS executes for ALL users viewing the FAQ page, not just admins.
- Session hijacking: Steal session cookies of all users viewing the FAQ.
- Phishing: Display fake login forms to steal credentials.
- Worm propagation: Self-replicating XSS that creates new FAQs with the same payload.
- Malware distribution: Redirect users to malicious sites.
Note: While planting the payload requires admin access, the XSS executes for all visitors (public-facing). This is not self-XSS.
AnalysisAI
Stored cross-site scripting (XSS) in phpMyFAQ allows authenticated administrators to inject unquoted or single-quoted event handler attributes that bypass the content sanitization pipeline, resulting in arbitrary JavaScript execution for all FAQ page visitors. The vulnerability exists in the removeAttributes() regex filter (line 174 of Filter.php) which only matches double-quoted HTML attributes, allowing payloads like <img src=x onerror=alert(1)> to persist and execute in the browser when the F
Technical ContextAI
phpMyFAQ implements a multi-stage sanitization pipeline for FAQ content that begins with PHP's FILTER_SANITIZE_SPECIAL_CHARS (encoding HTML metacharacters to entities), followed by html_entity_decode() to revert those entities, and finally a custom removeAttributes() method intended to strip dangerous HTML attributes. The root cause resides in the regex pattern at line 174 of phpmyfaq/src/phpMyFAQ/Filter.php: '/[a-z]+=\\
RemediationAI
Upgrade phpMyFAQ to the patched version released in response to GHSA-cv2g-8cj8-vgc7; exact version numbers are available in the GitHub Security Advisory at https://github.com/thorsten/phpMyFAQ/security/advisories/GHSA-cv2g-8cj8-vgc7. The primary fix is to replace the incomplete regex-based attribute removal with comprehensive HTML sanitization; the removeAttributes() method must be updated to match attributes with single quotes, unquoted values, and all event handler variants, or preferably replaced with a mature HTML sanitization library (e.g., HTML Purifier or DOMPurify). As an interim workaround prior to patching, disable the |raw filter in faq.twig line 36 by replacing {{ question | raw }} with {{ question }} to apply HTML entity encoding at render time, though this may affect intentional HTML formatting in FAQ titles. Additionally, implement Content Security Policy (CSP) headers with script-src 'self' and no inline script exceptions to mitigate XSS impact even if the sanitization bypass occurs. Review FAQ creation permissions and audit existing FAQ content for malicious payloads using the patterns described in the vulnerability report (onerror=, onload=, ontoggle= without double quotes). Detailed remediation steps and patched versions are documented in the GitHub advisory linked above.
sapi/cgi/cgi_main.c in PHP before 5.3.12 and 5.4.x before 5.4.2, when configured as a CGI script (aka php-cgi), does not
(1) boardData102.php, (2) boardData103.php, (3) boardDataJP.php, (4) boardDataNA.php, and (5) boardDataWW.php in Netgear
ProjectSend versions prior to r1720 are affected by an improper authentication vulnerability. Rated critical severity (C
Roundcube Webmail contains a critical PHP object deserialization vulnerability (CVE-2025-49113, CVSS 9.9) that allows au
Util/PHP/eval-stdin.php in PHPUnit before 4.8.28 and 5.x before 5.6.3 allows remote attackers to execute arbitrary PHP c
Palo Alto Networks PAN-OS management web interface contains an authentication bypass allowing unauthenticated attackers
Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re
Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re
The get_referers function in /opt/ws/bin/sblistpack in Sophos Web Appliance before 3.7.9.1 and 3.8 before 3.8.1.1 allows
The Backup Migration plugin for WordPress is vulnerable to Remote Code Execution in all versions up to, and including, 1
NetAlertX (formerly PiAlert) versions 23.01.14 through 24.x before 24.10.12 allow unauthenticated command injection thro
The GiveWP - Donation Plugin and Fundraising Platform plugin for WordPress is vulnerable to PHP Object Injection in all
Same weakness CWE-79 – Cross-site Scripting (XSS)
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-18260
GHSA-cv2g-8cj8-vgc7