Cross-site Scripting (XSS) - Stored in thorsten/phpmyfaq
Description
Cross-site Scripting (XSS) - Stored in GitHub repository thorsten/phpmyfaq prior to 3.1.17.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Stored XSS in phpMyFAQ prior to 3.1.17 allows attackers to inject arbitrary JavaScript via tag editing functionality.
Vulnerability
Description A stored cross-site scripting (XSS) vulnerability exists in GitHub repository thorsten/phpmyfaq prior to version 3.1.17. The root cause is insufficient sanitization of user-supplied input when editing tags; the application failed to escape HTML entities such as <, >, ", ', and & before rendering them in the Document Object Model (DOM) using $(...).html(). This allows an attacker to inject arbitrary JavaScript that is executed in the context of a victim's browser session [1][3].
Exploitation
An attacker with the ability to submit or modify tags (for example, authenticated users with permission to manage FAQ tags) can craft a malicious tag value containing HTML/JavaScript payloads. The injected script is stored on the server and later served to any user who views the affected tag. No special network position is required beyond access to the tag editing interface; the vulnerability is triggered when the browser processes the unsanitized input. The commit that fixes the issue adds a missing escape() call to convert HTML special characters before inserting user-controlled data into the DOM [3][4].
Impact
A successful attack can lead to session hijacking, credential theft, or other actions that a malicious script can perform on behalf of the victim, such as modifying FAQ content or executing administrative operations if the victim has elevated privileges. The stored nature of this XSS increases its severity, as the payload persists until the FAQ entry is removed or the tag is corrected [2].
Mitigation
The vulnerability is fixed in phpMyFAQ version 3.1.17. Users should upgrade immediately. No workarounds have been publicly documented, but restricting tag editing privileges to trusted users can reduce the risk. The fix, visible in commit 1037a8f, ensures user input passed through the input.val().replace(/\//g, '/') path is also escaped via the client-side escape() function [3][4].
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
thorsten/phpmyfaqPackagist | < 3.1.17 | 3.1.17 |
Affected products
2- thorsten/thorsten/phpmyfaqv5Range: unspecified
Patches
11037a8f012e0fix: added missing conversion to HTML entities
2 files changed · +7 −6
phpmyfaq/admin/ajax.tags.php+2 −1 modified@@ -17,6 +17,7 @@ use phpMyFAQ\Filter; use phpMyFAQ\Helper\HttpHelper; +use phpMyFAQ\Strings; use phpMyFAQ\Tags; use phpMyFAQ\Entity\TagEntity as TagEntity; @@ -55,7 +56,7 @@ ++$i; if ($i <= PMF_TAGS_AUTOCOMPLETE_RESULT_SET_SIZE) { $currentTag = new stdClass(); - $currentTag->tagName = $tagName; + $currentTag->tagName = Strings::htmlentities($tagName); $tagNames[] = $currentTag; } }
phpmyfaq/admin/assets/js/tags.js+5 −5 modified@@ -24,7 +24,7 @@ document.addEventListener('DOMContentLoaded', () => { span.replaceWith('<input name="tag" class="form-control" data-tag-id="' + id + '" value="' + span.html() + '">'); } else { const input = $('input[data-tag-id="' + id + '"]'); - input.replaceWith('<span data-tag-id="' + id + '">' + input.val().replace(/\//g, '/') + '</span>'); + input.replaceWith('<span data-tag-id="' + id + '">' + escape(input.val().replace(/\//g, '/')) + '</span>'); } }); @@ -36,10 +36,6 @@ document.addEventListener('DOMContentLoaded', () => { const tag = input.val(); const csrf = $('input[name=csrf]').val(); - const escape = (unsafe) => { - return unsafe.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"').replaceAll("'", '''); - } - $.ajax({ url: 'index.php?action=ajax&ajax=tags&ajaxaction=update', type: 'POST', @@ -59,4 +55,8 @@ document.addEventListener('DOMContentLoaded', () => { return false; }); + + const escape = (unsafe) => { + return unsafe.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"').replaceAll("'", '''); + } });
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4News mentions
0No linked articles in our index yet.