• Severity: CVSS 9.6 (Critical) · CWE-200
  • Affected: LibreChat ≤ 0.8.3 (npm package)
  • Patched: v0.8.4-rc1 (June 2, 2026) · Exploitation: PoC public, no in-the-wild exploitation confirmed at time of writing

Introduction

CVE-2026-32625 was published on June 2, 2026, and stems from a design mistake in LibreChat’s Model Context Protocol (MCP) server integration. LibreChat, a widely-deployed open-source ChatGPT alternative that supports OpenAI, Anthropic, Google, and other AI providers, allows authenticated users to configure external MCP servers via a REST API endpoint. In versions up to and including 0.8.3, those user-supplied server URLs are passed through a Zod validation schema that actively resolves ${VAR} template placeholders against the application server’s own process.env.

The weakness is classified as CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor). Exploitation requires only a valid, low-privilege user account. No administrative rights, no special roles, no social engineering of another user. The CVSS 3.1 vector AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N reflects that reality: network-reachable, low complexity, low privileges, no user interaction, and a changed scope because the impact cascades beyond the LibreChat process itself.

Cloud-hosted or SaaS deployments of LibreChat are subject to the same conditions as self-hosted instances, what matters is whether the MCP server creation endpoint is accessible to authenticated users and whether sensitive secrets are held in environment variables, which they are by default in virtually every standard LibreChat deployment.


What Happened

The root cause lives in packages/data-provider/src/mcp.ts. The Zod schema for MCP server URL fields, covering SSE, HTTP, and WebSocket connection types wraps each URL with a .transform() call that invokes extractEnvVariable(). That function, defined in packages/data-provider/src/utils.ts, scans the input string for any pattern matching \${[^}]+}, then unconditionally replaces each match with the corresponding value from process.env.

This variable-expansion behaviour was originally designed for administrator-managed configuration in librechat.yaml, where substituting environment variables into server definitions makes sense. The mistake was that the same transformed schema MCPServerUserInputSchema was also applied to the user-facing POST /api/mcp/servers endpoint. When a user submits a URL, the Zod validation runs first, expanding any variable references in the URL string before the resolved URL is stored and used.

After validation, LibreChat immediately calls MCPServerInspector.inspect() to probe the newly registered server for its available tools. That probe is an outbound HTTP GET request to the resolved URL. If the URL was crafted to point at an attacker-controlled host, the secret values are transmitted as query parameters in that request visible in the attacker’s web server logs in plain text.

It is also worth noting that LibreChat’s existing SSRF protection mechanism blocks connections to private IP ranges such as 127.0.0.1. This protection is completely ineffective here because the attacker supplies an external domain, the secrets travel to the public internet, not to internal services.

A public proof-of-concept was included in the GitHub Security Advisory at the time of disclosure.


Attack Sequence

An attacker begins by registering any standard LibreChat user account, or by compromising one that already exists. They then craft a POST request to the POST /api/mcp/servers endpoint with a JSON body containing a malicious SSE-type MCP server configuration. The URL in that configuration is set to a domain they control, with environment variable placeholders embedded in the query string. For example, pointing to a server they control with ?jwt=[JWT_SECRET]&key=[CREDS_KEY]&iv=[CREDS_IV] expressed as template variables.

When the request reaches the LibreChat server, Zod’s .transform() runs during input validation. The extractEnvVariable() function matches each placeholder, looks up its corresponding key in process.env, and substitutes the live value into the URL string. This happens silently, before any domain allow-listing or SSRF check can evaluate the destination. The resulting URL, now carrying the actual secret values as query parameters passes schema validation.

LibreChat immediately invokes MCPServerInspector.inspect() on the freshly stored configuration. The inspector sends a GET request to the resolved URL in order to discover the server’s tools and capabilities. That request arrives at the attacker’s listener with all three secrets embedded in the URL. The entire sequence from POST submission to secret receipt on the attacker’s side takes under a second.

At no point does the victim need to take any action. No administrator approval is required, and no alert is generated by default.


Why This Is Especially Dangerous

The danger here goes well beyond a single credential disclosure. The secrets exposed are the load-bearing pillars of LibreChat’s entire security model:

  • CREDS_KEY and CREDS_IV are the AES-256-CBC encryption key and initialisation vector used to protect every third-party API key stored in the database. OpenAI, Anthropic, Google, and others, as well as OAuth tokens and users’ private plugin credentials. With these values, an attacker can decrypt every stored credential in the MongoDB database.
  • JWT_SECRET is the symmetric signing key for JSON Web Tokens. Possession of this key lets an attacker forge valid authentication tokens for any user account on the platform, including administrators, without needing a password.
  • MONGO_URI is the database connection string, which typically includes the MongoDB username and password. This gives the attacker direct read-write access to the entire application dataset.

The combination means that a single exploitation event can result in full takeover of the LibreChat installation: all stored AI provider credentials decrypted, all user sessions forgeable, and the underlying database directly accessible. The attacker needs no other tools beyond an initial login.

Teams running LibreChat on behalf of customers, as part of an internal AI platform, or in a shared-user environment face the highest exposure because any one of their users can trigger this without any trace of malicious intent in the application’s normal logs.


Affected Versions

BranchVulnerable VersionsFix Available
LibreChat (npm)≤ 0.8.3v0.8.4-rc1 and v0.8.4 stable

The patch was first available in v0.8.4-rc1, released on June 2, 2026, the same day as disclosure. The stable v0.8.4 release followed shortly after. All earlier versions of LibreChat with MCP server support are affected regardless of configuration, as long as the MCP server creation endpoint is accessible to authenticated users.

LibreChat instances running in restricted environments where no user-level MCP server creation is possible are not exploitable via this path, but that is not the default configuration.


Mitigations

1. Upgrade to v0.8.4 or later immediately. The fix, landed in PR #12260 and labelled “Prevent Env-Variable Exfil. via Placeholder Injection”, removes the .transform(extractEnvVariable) call from MCPServerUserInputSchema. From v0.8.4 onward, environment variable expansion is no longer applied to user-supplied MCP server URLs. Upgrade using:

git fetch --tags
git checkout v0.8.4
npm install
npm run build

2. Rotate all exposed secrets immediately if you were running a vulnerable version. Even if you have no evidence of exploitation, treat these secrets as compromised. Generate fresh values for CREDS_KEY, CREDS_IV, JWT_SECRET, and rotate the MONGO_URI credential:

export CREDS_KEY="$(openssl rand -hex 32)"
export CREDS_IV="$(openssl rand -hex 16)"
export JWT_SECRET="$(openssl rand -hex 64)"

After rotating CREDS_KEY and CREDS_IV, all stored third-party API credentials in the database will need to be re-encrypted. After rotating JWT_SECRET, all active user sessions will be invalidated and users will need to re-authenticate.

3. Restrict MCP server creation to administrators as a temporary workaround. If you cannot upgrade immediately, disable user-level MCP server configuration via LibreChat’s access control settings. This removes the attack surface without patching but does not address the underlying schema defect.

4. Apply egress filtering on the LibreChat container. Restrict outbound HTTP connections from the LibreChat process to a defined allow-list of known MCP server domains. This would have prevented the secret exfiltration even on a vulnerable instance by blocking the connection to the attacker-controlled domain.

5. Audit your MongoDB mcpServers collection. Inspect stored MCP server URLs for any entries whose url field contains ${ substrings. Their presence would indicate that a payload was submitted and depending on how the record was stored, may indicate that the Zod transform ran and expanded the variables before writing.


Indicators of Compromise

No public IoC hashes or known malicious IPs have been published as of the time of writing. Exploitation leaves minimal application-layer footprint because the secret exfiltration happens during what appears to be a normal MCP configuration request. Use the following behavioural checklist to hunt for evidence of exploitation in your environment.

On the application host / in process logs

  • POST requests to /api/mcp/servers from standard user accounts (non-admin roles), particularly any created shortly before this CVE became public knowledge.
  • Any MCP server record whose stored URL contains %24%7B (URL-encoded ${), this would suggest the placeholder was submitted but not expanded, which may indicate a failed attempt or a partial bypass.
  • Node.js process logs showing outbound HTTP connections to domains not on your known MCP server list, especially occurring immediately after a POST /api/mcp/servers event.

In egress / proxy logs

  • Outbound GET requests from the LibreChat container to unexpected external hosts, bearing query parameters that consist of long hex or base64 strings (characteristic of AES key material or JWT secrets).
  • First-seen connections to domains registered recently or hosted on residential or VPS infrastructure.

In the MongoDB database

  • Records in the mcpServers collection with URLs pointing to webhook aggregators (webhook.site, requestbin.net, pipedream.net, etc.) or to non-standard ports on public IPs.
  • Any mcpServers entry created by a non-administrative account.

Configuration integrity

  • Unexpected changes to CREDS_KEY, CREDS_IV, or JWT_SECRET in your environment file or secrets manager (indicating a post-exploitation rotation attempt by an insider).
  • User sessions authenticated after a period when no legitimate logins should have occurred, a possible sign of JWT forgery using the exposed JWT_SECRET.

Check back against the GitHub Security Advisory (GHSA-4pcc-j6m6-wcwx) for any additional IoC updates as the community’s analysis matures.


References