Jun 23, 2026·5 min read·6 visits
An incomplete fix for CVE-2026-24421 in phpMyFAQ leaves four REST API endpoints vulnerable to missing authorization, enabling low-privileged authenticated users to modify categories, FAQs, and system questions without the required role permissions.
An incomplete security patch for CVE-2026-24421 in phpMyFAQ allows authenticated low-privileged users to bypass role-based access controls. While the initial patch addressed missing authorization in the BackupController, it left four critical write-enabled endpoints vulnerable. This allows remote attackers with a valid low-privilege API token to perform unauthorized data modifications, creating categories, creating FAQs, updating FAQs, and injecting questions directly into the database.
phpMyFAQ is an open-source, web-based Frequently Asked Questions (FAQ) system. Its architecture features a REST API that facilitates administrative integration and external system synchronization. Because the platform is designed to manage public and private documentation structures, security boundaries are enforced through a strict role-based access control (RBAC) model.
This vulnerability, designated as CVE-2026-49205, belongs to the Missing Authorization class (CWE-862). It stems from an incomplete remediation of CVE-2026-24421, where access checks were fixed only in the BackupController. The underlying issue remained unresolved across several other write-enabled public API endpoints, exposing an unauthorized write interface to low-privileged accounts.
The attack surface is accessible to any user who holds a valid low-privilege API token. Because the system fails to check individual user permissions before executing modifications, an attacker can manipulate content and configurations, altering the integrity of the FAQ platform.
The root cause of CVE-2026-49205 is a breakdown in function-level authorization checks within the REST API controller layer. In a secure implementation, API routes that alter the state of the application must enforce two independent checks: authentication (verifying identity) and authorization (verifying permissions).
In phpMyFAQ, authentication is processed by calling $this->hasValidToken(), which verifies that the request context contains a valid API key. However, this function only guarantees token validity. It does not evaluate whether the user associated with that token is permitted to perform administrative or state-altering actions.
In versions prior to 4.1.4, four key write endpoints did not execute the secondary validation helper $this->userHasPermission(). Consequently, once the API key is verified as syntactically correct, the controller processes the write payload unconditionally, treating low-privileged users and administrators identically on these routes.
An examination of the vulnerable codebase reveals that CategoryController.php, FaqController.php, and QuestionController.php lacked user-role validation inside their write methods. The create() method in CategoryController.php demonstrated this omission, executing database operations immediately after verifying the API token.
// Vulnerable Implementation (CategoryController.php)
public function create(Request $request): JsonResponse
{
$this->hasValidToken(); // Only checks if the API key exists and is valid
[$currentUser, $currentGroups] = CurrentUser::getCurrentUserGroupId($this->currentUser);
// Proceeds to insert data without verifying if the user has PermissionType::CATEGORY_ADD
}The patch introduced specific role checks immediately following token verification. The code blocks below show the updated validation sequence, explicitly requiring specific permissions from the PermissionType enum:
// Patched Implementation (CategoryController.php)
use phpMyFAQ\Enums\PermissionType;
// ...
public function create(Request $request): JsonResponse
{
$this->hasValidToken();
$this->userHasPermission(PermissionType::CATEGORY_ADD); // Enforces authorized group checks
[$currentUser, $currentGroups] = CurrentUser::getCurrentUserGroupId($this->currentUser);
}While the addition of userHasPermission() resolves the missing authorization pathway, security audits must ensure that the context variables initialized in CurrentUser::getCurrentUserGroupId() map reliably to the active API token context. If an API key is evaluated system-wide rather than tied to a specific user, the permission check could still resolve as true.
An attacker can exploit this vulnerability by authenticating to the platform as a standard low-privileged user to retrieve a valid API token. No administrative privilege or complex configuration is required to initiate the attack.
With a valid token, the attacker directs HTTP POST or PUT requests to the vulnerable endpoints. Because the backend code only verifies token validity, the request bypasses role limits, allowing the attacker to perform write operations.
An attacker can use the following HTTP payload to inject an unauthorized category into the system, altering the structural configuration of the FAQ application:
POST /api/v4.0/category HTTP/1.1
Host: target-faq-site.example.com
Authorization: Bearer <VALID_LOW_PRIVILEGE_TOKEN>
Content-Type: application/json
{
"name": "Unauthorized Malicious Category",
"description": "Injected via missing authorization vulnerability",
"parent_id": 0
}Similarly, targeting the FaqController::update endpoint via a PUT /api/v4.0/faq request allows unauthorized modifications to existing documentation, facilitating the distribution of misleading information or malicious external hyperlinks.
The exploitation of CVE-2026-49205 compromises both data integrity and content authorization. Although classified as Medium severity with a CVSS score of 6.5, the practical impact is significant for organizations that rely on phpMyFAQ for trusted reference documentation.
Unauthorized modification of FAQ items and categories allows malicious actors to execute horizontal and vertical privilege escalation within the context of the application's data layer. By bypassing content moderation queues, attackers can insert malicious guidelines or modify administrative procedures.
While there is no threat intelligence indicating active exploitation or weaponized public exploits in the wild, the public exposure of these API endpoints makes them vulnerable to scanning and automated abuse. This vulnerability highlights the risks of incomplete security patching during vulnerability remediation.
The recommended remediation is to upgrade phpMyFAQ immediately to version 4.1.4 or higher. This release integrates role authorization checks on all write-based REST API controllers.
For systems where an immediate upgrade is not feasible, a manual patch can be applied. Administrators must modify the vulnerable controller files to import the PermissionType enum and invoke $this->userHasPermission() directly under $this->hasValidToken() in the corresponding methods.
// Manual Mitigation Example for FaqController.php
use phpMyFAQ\Enums\PermissionType;
// ...
public function create(Request $request): JsonResponse {
$this->hasValidToken();
$this->userHasPermission(PermissionType::FAQ_ADD);
// ...
}In addition to manual patching, configure web application firewalls (WAFs) to monitor and restrict access to the /api/v4.0/ endpoints. Verify that incoming administrative-level POST and PUT requests originate only from trusted networks or highly privileged system users.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
phpMyFAQ thorsten | < 4.1.4 | 4.1.4 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-862: Missing Authorization |
| Attack Vector | Network |
| CVSS v3.1 Score | 6.5 (Medium) |
| Exploit Maturity | None / Unproven |
| EPSS Score | 0.0024 |
| KEV Status | Not Listed |
The application does not perform an authorization check when an actor attempts to access a resource or perform an action.
An incorrect authorization vulnerability (CWE-863) in Snipe-IT versions prior to 8.6.0 allows authenticated, low-privileged users with granular 'users.edit' permissions to modify restricted user flags ('activated' and 'ldap_import') and merge high-privileged administrator accounts into standard user accounts. This allows an attacker to lock administrators out of the system or completely hijack administrator accounts.
An open redirect vulnerability exists in Flask-Security versions up to and including 5.8.0. This flaw allows remote, unauthenticated attackers to perform open redirects by exploiting a parser differential between Python's standard library urlsplit() function and modern web browsers when subdomain redirection is allowed.
An in-depth security audit of the skillctl command-line package manager revealed five critical and high-severity security vulnerabilities. The identified flaws span parameter-level command argument injection via the source_sha parameter, uncontrolled resource consumption (Denial of Service) through unnamed UNIX FIFOs and character devices, directory path traversal in the destination argument, commit-message trailer forgery via newline injection in skill names, and local credential exfiltration leveraging UNIX hardlinks. These vulnerabilities represent significant vectors for workstation compromise when executing agentic tasks in repositories containing untrusted files or pull requests. Remediation was introduced in version v0.1.3.
CVE-2026-48153 is a Server-Side Request Forgery (SSRF) vulnerability in the Budibase OAuth2 SDK prior to version 3.39.0. It allows authenticated low-privileged users to bypass outbound network security blacklists and send arbitrary requests to internal subnets or cloud metadata services.
The self-hosted Slack Nebula VPN control plane, nebula-mesh, stored high-privilege enrollment tokens in plaintext inside its SQLite database. This flaw allowed any adversary with read access to the database to retrieve pending tokens and enroll unauthorized hosts into the secure VPN mesh.
The devbridge-autocomplete package (jQuery-Autocomplete) fails to escape category headers and suggestion values when using default formatters formatGroup and formatResult. If suggestions contain untrusted input, arbitrary HTML and JavaScript execute directly in the victim's browser session.