Advisories for Composer/Phpmyfaq/Phpmyfaq package

2026

phpMyFAQ's Missing CONFIGURATION_EDIT Permission Check on 12 Admin API Configuration Tab Endpoints Allows Information Disclosure by Any Authenticated User

12 endpoints in ConfigurationTabController.php use userIsAuthenticated() (login-only check) instead of userHasPermission(PermissionType::CONFIGURATION_EDIT). This allows any authenticated user — including ones with zero admin permissions — to enumerate system configuration metadata including the permission model, active template, cache backend, mail provider, and translation provider.

phpMyFAQ's Missing Authorization on Tag Deletion Allows Any Authenticated User to Delete Tags

The TagController::delete() endpoint at DELETE /admin/api/content/tags/{tagId} only verifies that the user is logged in (userIsAuthenticated()), but does not check any permission. Any authenticated user — including regular non-admin frontend users — can delete any tag by ID. This contrasts with TagController::update() and TagController::search(), which both enforce the FAQ_EDIT permission.

phpMyFAQ: Path Traversal in Client::deleteClientFolder enables arbitrary directory deletion by non-super-admin admins

Client::deleteClientFolder() in phpmyfaq/src/phpMyFAQ/Instance/Client.php:583 takes a URL from the caller, strips the https:// prefix, and passes the remainder to Filesystem::deleteDirectory() relative to the multisite clientFolder. No path-traversal validation runs. An admin with the INSTANCE_DELETE permission (a role short of SUPER_ADMIN) submits https://../../../<path> as the client URL and the server recursively deletes arbitrary directories under the web user's rights. Same pattern and reachability as GHSA-38m8-xrfj-v38x, which the project accepted at High severity …

phpMyFAQ: Ordinary Authenticated User Can Access Admin-Only API Endpoints Due to Insufficient Authorization Check in phpMyFAQ

A review of phpMyFAQ-main uncovered an authorization issue in the admin-api routes. Several backend endpoints only check whether the caller is logged in. They do not verify that the caller actually has backend or administrative privileges. As a result, a normal frontend user can access API endpoints that are clearly intended for administrative use. During local reproduction, a regular user account was able to request /admin/api/index.php/dashboard/versions and receive a successful …

phpMyFAQ has unauthenticated SQL injection via User-Agent header in BuiltinCaptcha

BuiltinCaptcha::garbageCollector() and BuiltinCaptcha::saveCaptcha() at phpmyfaq/src/phpMyFAQ/Captcha/BuiltinCaptcha.php:298 and :330 interpolate the User-Agent header and client IP address into DELETE and INSERT queries with sprintf and no escaping. Both methods run on every hit to the public GET /api/captcha endpoint, which requires no authentication. An unauthenticated attacker sets the User-Agent header to a crafted SQL payload and runs SLEEP(), BENCHMARK(), or time-based blind extraction against the database that backs phpMyFAQ. Verified live against …

phpMyFAQ has unauthenticated FAQ permission bypass via getFaqBySolutionId fallback query

The public /solution_id_{id}.html route calls Faq::getIdFromSolutionId() in phpmyfaq/src/phpMyFAQ/Faq.php:1312. That query joins faqdata with faqcategoryrelations solely by solution_id and returns the matching FAQ's id, lang, thema (title), and category_id with no permission filter. An unauthenticated visitor hits the route with a sequential integer and the server 301-redirects to /content/<category>/<id>/<lang>/<title-slug>.html, leaking the FAQ's existence, internal id, language, category binding, and title via the redirect's Location header and the redirected page's canonical link, …

phpMyFAQ has stored XSS via | raw Filter in search.twig — html_entity_decode(strip_tags()) Bypass in Search Result Rendering

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 …

phpMyFAQ has Stored XSS in FAQ Question/Answer via Encode-Decode Bypass of removeAttributes() Sanitization

The FAQ creation and update endpoints in phpMyFAQ apply FILTER_SANITIZE_SPECIAL_CHARS (which HTML-encodes input), then immediately call html_entity_decode() which reverses the encoding, followed by Filter::removeAttributes() which only strips HTML attributes — not tags. This allows <script>, <iframe>, <object>, and <embed> tags to be stored in the database and rendered unescaped via {{ answer|raw }} and {{ question|raw }} in the Twig template, causing JavaScript execution in every visitor's browser.

phpMyFAQ has SQL Injection in CurrentUser::setTokenData through unescaped OAuth token fields

CurrentUser::setTokenData() in phpmyfaq/src/phpMyFAQ/User/CurrentUser.php at lines 515-534 builds a SQL UPDATE statement with sprintf and interpolates OAuth token fields (refresh_token, access_token, code_verifier, and json_encode($token['jwt'])) without calling $db->escape(). Sibling methods setAuthSource() and setRememberMe() in the same file do call $db->escape() on user-controlled values, so the omission is local to this method. An attacker (Bob) whose Azure AD display name contains a single quote (for example O'Brien, or a deliberate SQL payload) breaks …

phpMyFAQ has an Authorization Bypass in All Admin Pages Due to Non-Terminating Permission Check

AbstractAdministrationController::userHasPermission() catches the ForbiddenException thrown when a user lacks a specific permission, sends a "forbidden" HTML page via $response->send(), but does not terminate execution. The calling controller method continues to execute, fetches protected data, renders the full template, and returns it as a Response. The final $response->send() in admin/index.php outputs the protected page content after the forbidden page, leaking all permission-protected admin data to any authenticated admin user regardless of …

phpMyFAQ has a SVG Sanitizer Entity Decoding Depth Limit Bypass Leading to Stored XSS

The SvgSanitizer::decodeAllEntities() method limits recursive entity decoding to 5 iterations. By wrapping each character of javascript in an href attribute value with 5 levels of &amp; encoding around numeric HTML entities (e.g., &amp;amp;amp;amp;amp;#106; for j), an attacker can bypass both isSafe() detection and sanitize() removal. The uploaded SVG is served from the application origin with image/svg+xml content type, and the browser's XML parser fully decodes the remaining &#NNN; entities, resulting …

phpMyFAQ enables unauthenticated 2FA brute-force attack via /admin/check acceptance of arbitrary user-id

The /admin/check endpoint in AuthenticationController implements SkipsAuthenticationCheck, making it reachable without any prior authentication. An anonymous attacker (Bob) can POST arbitrary user-id and token values to brute-force any user's 6-digit TOTP code. No rate limiting exists. The 10^6 keyspace is exhaustible in minutes. Reachability confirmed against a default install: unauthenticated POST /admin/check with a user-id body field returns HTTP 302 to /admin/token?user-id=<value>, echoing the attacker-supplied user id without any binding …

phpMyFAQ: Stored XSS via Regex Bypass in Filter::removeAttributes()

The sanitization pipeline for FAQ content is: Filter::filterVar($input, FILTER_SANITIZE_SPECIAL_CHARS) — encodes <, >, ", ', & to HTML entities html_entity_decode($input, ENT_QUOTES | ENT_HTML5) — decodes entities back to characters Filter::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 …

phpMyFAQ: Path Traversal - Arbitrary File Deletion in MediaBrowserController

The MediaBrowserController::index() method handles file deletion for the media browser. When the fileRemove action is triggered, the user-supplied name parameter is concatenated with the base upload directory path without any path traversal validation. The FILTER_SANITIZE_SPECIAL_CHARS filter only encodes HTML special characters (&, ', ", <, >) and characters with ASCII value < 32, and does not prevent directory traversal sequences like ../. Additionally, the endpoint does not validate CSRF tokens, …

phpMyFAQ is Vulnerable to Stored XSS via Unsanitized Email Field in Admin FAQ Editor

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 "alert(1)"@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.

2025

phpMyFAQ contains a CSV injection vulnerability

phpMyFAQ 3.1.12 contains a CSV injection vulnerability that allows authenticated users to inject malicious formulas into their profile names. Attackers can modify their user profile name with a payload like 'calc|a!z|' to trigger code execution when an administrator exports user data as a CSV file.

phpMyFAQ has Authenticated SQL Injection in Configuration Update Functionality

An authenticated SQL injection vulnerability in the main configuration update functionality of phpMyFAQ (v4.0.13 and prior) allows a privileged user with 'Configuration Edit' permissions to execute arbitrary SQL commands. Successful exploitation can lead to a full compromise of the database, including reading, modifying, or deleting all data, as well as potential remote code execution depending on the database configuration.

phpMyFAQ Vulnerable to Stored HTML Injection at FAQ

Due to insufficient validation on the content of new FAQ posts, it is possible for authenticated users to inject malicious HTML or JavaScript code that can impact other users viewing the FAQ. This vulnerability arises when user-provided inputs in FAQ entries are not sanitized or escaped before being rendered on the page.

2024

phpMyFAQ Stored HTML Injection at contentLink

Due to insufficient validation on the contentLink parameter, it is possible for unauthenticated users to inject HTML code to the page which might affect other users. Also, requires that adding new FAQs is allowed for guests and that the admin doesn't check the content of a newly added FAQ.

phpMyFAQ stored Cross-site Scripting at user email

The email field in phpMyFAQ's user control panel page is vulnerable to stored XSS attacks due to the inadequacy of PHP's FILTER_VALIDATE_EMAIL function, which only validates the email format, not its content. This vulnerability enables an attacker to execute arbitrary client-side JavaScript within the context of another user's phpMyFAQ session.

phpMyFAQ SQL injections at insertentry & saveentry

A SQL injection vulnerability has been discovered in the insertentry & saveentry when modifying records due to improper escaping of the email address. This allows any authenticated user with the rights to add/edit FAQ news to exploit this vulnerability to exfiltrate data, take over accounts and in some cases, even achieve RCE.

phpMyFAQ SQL Injection at "Save News"

A SQL injection vulnerability has been discovered in the the "Add News" functionality due to improper escaping of the email address. This allows any authenticated user with the rights to add/edit FAQ news to exploit this vulnerability to exfiltrate data, take over accounts and in some cases, even achieve RCE.

Incorrect Authorization

phpMyFAQ is an Open Source FAQ web application for PHP 8.1+ and MySQL, PostgreSQL and other databases. The 'sharing FAQ' functionality allows any unauthenticated actor to misuse the phpMyFAQ application to send arbitrary emails to a large range of targets. The phpMyFAQ application has a functionality where anyone can share a FAQ item to others. The front-end of this functionality allows any phpMyFAQ articles to be shared with 5 email …

Improper Access Control

phpMyFAQ is an open source FAQ web application for PHP 8.1+ and MySQL, PostgreSQL and other databases. phpMyFAQ's user removal page allows an attacker to spoof another user's detail, and in turn make a compelling phishing case for removing another user's account. The front-end of this page does not allow changing the form details, an attacker can utilize a proxy to intercept this request and submit other data. Upon submitting …

2022