CVE-2026-32629: Thorsten/phpmyfaq Cross-Site Scripting Vulnerability

MODERATE
Advisory Identifier: GHSA-98gw-w575-h2ph
CWE-20 CWE-79
Published
Advisory Summary

CVE-2026-32629 is a MODERATE cross-site scripting vulnerability (CWE-20: Improper Input Validation) affecting Thorsten/phpmyfaq libraries in the Packagist ecosystem. The issue involves phpmyfaq is vulnerable to stored xss via unsanitized email field in admin faq editor. Remediation is available by upgrading affected packages to version 4.1.1.

CVE-2026-32629 at a Glance

CVE Identifier CVE-2026-32629
GHSA Identifier GHSA-98gw-w575-h2ph
Severity MODERATE
CVSS v3.1 Base Score N/A
CWE Classification CWE-20: Improper Input Validation
Affected Product Thorsten/phpmyfaq
Package Ecosystem Packagist
Published Date
Last Updated

How to Fix CVE-2026-32629

To remediate this vulnerability, upgrade all affected Thorsten/phpmyfaq dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

thorsten/phpmyfaq fixed: 4.1.1
Upgrade thorsten/phpmyfaq to 4.1.1
phpmyfaq/phpmyfaq fixed: 4.1.1
Upgrade phpmyfaq/phpmyfaq to 4.1.1
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for thorsten/phpmyfaq

How to Check if You Are Affected

To determine whether your application is affected by CVE-2026-32629, inspect your project dependencies for Thorsten/phpmyfaq:

inspect dependencies for thorsten/phpmyfaq

Analyze the terminal output to locate any version of Thorsten/phpmyfaq in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 4.1.1), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-20: Improper Input Validation, where the product receives input or data, but it does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly. In Thorsten/phpmyfaq, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Summary An unauthenticated attacker can submit a guest FAQ with an email address that is syntactically valid per RFC 5321 (quoted local part) yet contains raw HTML — for example "<script>alert(1)</script>"@evil.com. PHP's FILTER_VALIDATE_EMAIL accepts this email as valid. The email is stored in the database without HTML sanitization and later rendered in the admin FAQ editor template using Twig's |raw filter, which bypasses auto-escaping entirely. ### Details 1. PHP FILTER_VALIDATE_EMAIL accepts RFC-valid quoted local parts with dangerous characters phpmyfaq/src/phpMyFAQ/Controller/Frontend/Api/FaqController.php:99 $email = trim((string) Filter::filterVar($data->email, FILTER_VALIDATE_EMAIL)); PHP accepts "<script>alert(1)</script>"@evil.com as a valid email (RFC 5321 allows <, > inside quoted local parts). Confirmed: "<script>alert(1)</script>"@evil.com => string (valid, not false) 2. Email stored raw without HTML sanitization phpmyfaq/src/phpMyFAQ/Faq.php — email retrieved directly as $row->email from the database. 3. Admin Twig template renders email with |raw phpmyfaq/assets/templates/admin/content/faq.editor.twig:296 <input type="email" name="email" id="email" value="{{ faqData['email'] | raw }}" class="form-control"> Affected version: 4.2.0-alpha, commit f0dc86c8f ### PoC **The reproduction of the vulnerability was implemented with the help of AI while reviewing the source code to generate the proof-of-concept. Please kindly note this for reference. Since the vulnerability has already been confirmed directly in the source code, the proof-of-concept code may be considered as a reference only.** Please extract the attached compressed file and proceed. [poc.zip](https://github.com/user-attachments/files/25938058/poc.zip) 0. (docker compose -f docker-compose.yml down -v) 1. docker compose -f docker-compose.yml up -d mariadb php-fpm nginx 2. bash exploit.sh ----- 1. Access http://localhost:8888/admin/ 2. Log in with admin / Admin1234! 3. After logging in, check whether the URL remains http://localhost:8888/admin/ 4. Go to Content → FAQ Administration → edit "poc" → alert popup should appear If it does not appear, you can also access it directly via: http://localhost:8888/admin/faq/edit/1/en <img width="1388" height="239" alt="스크린샷 2026-03-12 오후 11 42 52" src="https://github.com/user-attachments/assets/b6d5446f-4eba-4cb2-9284-1bca4855142e" /> <img width="1171" height="92" alt="스크린샷 2026-03-12 오후 11 16 17" src="https://github.com/user-attachments/assets/3578e429-7106-4616-92ed-4167816d40f0" /> ### Impact When an administrator opens /admin/faq/edit/{id}/{lang} to review the pending FAQ, the injected script executes in the admin's browser context. This allows an attacker to: - Steal the administrator's session cookie → full admin account takeover - Perform arbitrary admin actions (create users, modify content, change configuration) - Pivot to further attacks on the server The attack chain requires no authentication. By default, records.allowNewFaqsForGuests=true allows unauthenticated FAQ submission, and records.defaultActivation=false guarantees the administrator must visit the edit page to review it. Note on captcha: The built-in captcha is enabled by default when the PHP gd extension is present (spam.enableCaptchaCode=true). This prevents fully automated exploitation but does not prevent a targeted manual attack — an attacker can solve the captcha once and submit the payload. ### Credits wooseokdotkim

CVE-2026-32629 Affected Thorsten/phpmyfaq Versions

2 component(s)
Fixed Versions:
4.1.1
Product / Package Ecosystem Affected Versions Fixed Version
thorsten/phpmyfaq
Packagist
< 4.1.1
4.1.1
phpmyfaq/phpmyfaq
Packagist
< 4.1.1
4.1.1

References

Frequently Asked Questions

What is CVE-2026-32629?
CVE-2026-32629 is a security vulnerability in Thorsten/phpmyfaq involving phpMyFAQ is Vulnerable to Stored XSS via Unsanitized Email Field in Admin FAQ Editor under CWE-20: Improper Input Validation.
Which Thorsten/phpmyfaq versions are affected?
Affected versions include releases prior to 4.1.1 across affected packages: thorsten/phpmyfaq, phpmyfaq/phpmyfaq.
What version fixes CVE-2026-32629?
Upgrading to 4.1.1 (or the latest patched release for your respective branch) resolves the vulnerability.
Is thorsten/phpmyfaq affected?
Yes, thorsten/phpmyfaq is affected in releases prior to 4.1.1. Upgrade your dependency to 4.1.1 or later.
Is phpmyfaq/phpmyfaq affected?
Yes, phpmyfaq/phpmyfaq is affected in releases prior to 4.1.1. Upgrade your dependency to 4.1.1 or later.
What CWE is associated with CVE-2026-32629?
CVE-2026-32629 is classified under CWE-20: Improper Input Validation (The product receives input or data, but it does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly.).
How can I check Packagist dependencies for CVE-2026-32629?
Run the dependency tree command: 'inspect dependencies for thorsten/phpmyfaq'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-98gw-w575-h2ph",
  "modified" : "2026-04-06T17:18:07Z",
  "published" : "2026-03-31T22:48:45Z",
  "aliases" : [ "CVE-2026-32629" ],
  "summary" : "phpMyFAQ is Vulnerable to Stored XSS via Unsanitized Email Field in Admin FAQ Editor",
  "details" : "### Summary\nAn unauthenticated attacker can submit a guest FAQ with an email address that is syntactically valid per RFC 5321 (quoted local part) yet contains raw HTML — for example \"<script>alert(1)</script>\"@evil.com. PHP's FILTER_VALIDATE_EMAIL accepts this email as valid. The email is stored in the database without HTML sanitization and later rendered in the admin FAQ editor template using Twig's |raw filter, which bypasses auto-escaping entirely.\n\n### Details\n1. PHP FILTER_VALIDATE_EMAIL accepts RFC-valid quoted local parts with dangerous characters\n\nphpmyfaq/src/phpMyFAQ/Controller/Frontend/Api/FaqController.php:99\n$email = trim((string) Filter::filterVar($data->email, FILTER_VALIDATE_EMAIL));\nPHP accepts \"<script>alert(1)</script>\"@evil.com as a valid email (RFC 5321 allows <, > inside quoted local parts). Confirmed:\n\"<script>alert(1)</script>\"@evil.com => string (valid, not false)\n\n2. Email stored raw without HTML sanitization\n\nphpmyfaq/src/phpMyFAQ/Faq.php — email retrieved directly as $row->email from the database.\n\n3. Admin Twig template renders email with |raw\n\nphpmyfaq/assets/templates/admin/content/faq.editor.twig:296\n<input type=\"email\" name=\"email\" id=\"email\" value=\"{{ faqData['email'] | raw }}\" class=\"form-control\">\n\nAffected version: 4.2.0-alpha, commit f0dc86c8f\n\n\n### PoC\n**The reproduction of the vulnerability was implemented with the help of AI while reviewing the source code to generate the proof-of-concept. Please kindly note this for reference. Since the vulnerability has already been confirmed directly in the source code, the proof-of-concept code may be considered as a reference only.**\n\nPlease extract the attached compressed file and proceed.\n[poc.zip](https://github.com/user-attachments/files/25938058/poc.zip)\n\n\n0. (docker compose -f docker-compose.yml down -v)\n1. docker compose -f docker-compose.yml up -d mariadb php-fpm nginx\n2. bash exploit.sh\n-----\n1. Access http://localhost:8888/admin/\n2. Log in with admin / Admin1234!\n3. After logging in, check whether the URL remains http://localhost:8888/admin/\n4. Go to Content → FAQ Administration → edit \"poc\" → alert popup should appear\nIf it does not appear, you can also access it directly via:\nhttp://localhost:8888/admin/faq/edit/1/en\n\n\n<img width=\"1388\" height=\"239\" alt=\"스크린샷 2026-03-12 오후 11 42 52\" src=\"https://github.com/user-attachments/assets/b6d5446f-4eba-4cb2-9284-1bca4855142e\" />\n<img width=\"1171\" height=\"92\" alt=\"스크린샷 2026-03-12 오후 11 16 17\" src=\"https://github.com/user-attachments/assets/3578e429-7106-4616-92ed-4167816d40f0\" />\n\n\n### Impact\nWhen an administrator opens /admin/faq/edit/{id}/{lang} to review the pending FAQ, the injected script executes in the admin's browser context. This allows an attacker to:\n\n- Steal the administrator's session cookie → full admin account takeover\n- Perform arbitrary admin actions (create users, modify content, change configuration)\n- Pivot to further attacks on the server\n\nThe attack chain requires no authentication. By default, records.allowNewFaqsForGuests=true allows unauthenticated FAQ submission, and records.defaultActivation=false guarantees the administrator must visit the edit page to review it.\n\nNote on captcha: The built-in captcha is enabled by default when the PHP gd extension is present (spam.enableCaptchaCode=true). This prevents fully automated exploitation but does not prevent a targeted manual attack — an attacker can solve the captcha once and submit the payload. \n\n### Credits\nwooseokdotkim",
  "severity" : [ {
    "type" : "CVSS_V4",
    "score" : "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N/E:P"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Packagist",
      "name" : "thorsten/phpmyfaq"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "4.1.1"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 4.1.0"
    }
  }, {
    "package" : {
      "ecosystem" : "Packagist",
      "name" : "phpmyfaq/phpmyfaq"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "4.1.1"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 4.1.0"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/thorsten/phpMyFAQ/security/advisories/GHSA-98gw-w575-h2ph"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-32629"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/thorsten/phpMyFAQ"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/thorsten/phpMyFAQ/releases/tag/4.1.1"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-20", "CWE-79" ],
    "severity" : "MODERATE",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-03-31T22:48:45Z",
    "nvd_published_at" : "2026-04-02T15:16:38Z"
  }
}