CVE-2026-31942
Description
LibreChat 0.7.6 and earlier has an IDOR in API keys management, allowing authenticated users to overwrite others' API keys.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
LibreChat 0.7.6 and earlier has an IDOR in API keys management, allowing authenticated users to overwrite others' API keys.
Vulnerability
LibreChat versions up to and including 0.7.6 contain an Insecure Direct Object Reference (IDOR) vulnerability in the API keys management endpoint (PUT /api/keys). This occurs because the JavaScript object spread operator ...req.body is applied after userId: req.user.id, allowing an authenticated user to inject a userId parameter in the request body to overwrite any other user's API keys, such as OpenAI, Anthropic, or Azure [1].
Exploitation
An attacker must first authenticate as a regular user and obtain a valid JWT token. They can then send a PUT request to the /api/keys endpoint with a crafted JSON body, including a userId parameter set to the victim's user ID, along with the name and value of the API key to be updated. For example: {"userId": "<victim_user_id>", "name": "openAI", "value": "sk-attacker-controlled-api-key"} [1].
Impact
Successful exploitation allows an attacker to replace a victim's API key configuration. This can lead to the victim's conversations being routed through the attacker's controlled keys, enabling monitoring of prompts and conversations. It can also result in denial of service by providing invalid keys, or potentially intercepting sensitive information within prompts. The impact includes high confidentiality and high integrity risks [1].
Mitigation
This vulnerability is patched in version 0.8.3-rc1. Users are advised to upgrade to a fixed version as soon as possible. No workarounds are disclosed in the available references [1].
AI Insight generated on Jun 2, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
14d04904af367✨ v0.7.7 (#6206)
12 files changed · +37 −17
api/package.json+1 −1 modified@@ -1,6 +1,6 @@ { "name": "@librechat/backend", - "version": "v0.7.7-rc1", + "version": "v0.7.7", "description": "", "scripts": { "start": "echo 'please run this from the root directory'",
CHANGELOG.md+16 −0 added@@ -0,0 +1,16 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [Unreleased] + +### ✨ New Features + +- 🪄 feat: Agent Artifacts by **@danny-avila** in [#5804](https://github.com/danny-avila/LibreChat/pull/5804) + +### ⚙️ Other Changes + +- 🔄 chore: Enforce 18next Language Keys by **@rubentalstra** in [#5803](https://github.com/danny-avila/LibreChat/pull/5803) +- 🔃 refactor: Parent Message ID Handling on Error, Update Translations, Bump Agents by **@danny-avila** in [#5833](https://github.com/danny-avila/LibreChat/pull/5833) + +---
client/package.json+1 −1 modified@@ -1,6 +1,6 @@ { "name": "@librechat/frontend", - "version": "v0.7.7-rc1", + "version": "v0.7.7", "description": "", "type": "module", "scripts": {
Dockerfile+1 −1 modified@@ -1,4 +1,4 @@ -# v0.7.7-rc1 +# v0.7.7 # Base node image FROM node:20-alpine AS node
Dockerfile.multi+1 −1 modified@@ -1,5 +1,5 @@ # Dockerfile.multi -# v0.7.7-rc1 +# v0.7.7 # Base for all builds FROM node:20-alpine AS base-min
e2e/jestSetup.js+1 −1 modified@@ -1,3 +1,3 @@ -// v0.7.7-rc1 +// v0.7.7 // See .env.test.example for an example of the '.env.test' file. require('dotenv').config({ path: './e2e/.env.test' });
package.json+1 −1 modified@@ -1,6 +1,6 @@ { "name": "LibreChat", - "version": "v0.7.7-rc1", + "version": "v0.7.7", "description": "", "workspaces": [ "api",
package-lock.json+6 −6 modified@@ -1,12 +1,12 @@ { "name": "LibreChat", - "version": "v0.7.7-rc1", + "version": "v0.7.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "LibreChat", - "version": "v0.7.7-rc1", + "version": "v0.7.7", "license": "ISC", "workspaces": [ "api", @@ -47,7 +47,7 @@ }, "api": { "name": "@librechat/backend", - "version": "v0.7.7-rc1", + "version": "v0.7.7", "license": "ISC", "dependencies": { "@anthropic-ai/sdk": "^0.37.0", @@ -2365,7 +2365,7 @@ }, "client": { "name": "@librechat/frontend", - "version": "v0.7.7-rc1", + "version": "v0.7.7", "license": "ISC", "dependencies": { "@ariakit/react": "^0.4.15", @@ -43556,7 +43556,7 @@ }, "packages/data-provider": { "name": "librechat-data-provider", - "version": "0.7.6998", + "version": "0.7.7", "license": "ISC", "dependencies": { "axios": "^1.7.7", @@ -43693,7 +43693,7 @@ }, "packages/mcp": { "name": "librechat-mcp", - "version": "1.0.0", + "version": "1.1.0", "license": "ISC", "dependencies": { "@modelcontextprotocol/sdk": "^1.6.1",
packages/data-provider/package.json+1 −1 modified@@ -1,6 +1,6 @@ { "name": "librechat-data-provider", - "version": "0.7.6998", + "version": "0.7.7", "description": "data services for librechat apps", "main": "dist/index.js", "module": "dist/index.es.js",
packages/data-provider/src/config.ts+1 −1 modified@@ -1173,7 +1173,7 @@ export enum TTSProviders { /** Enum for app-wide constants */ export enum Constants { /** Key for the app's version. */ - VERSION = 'v0.7.7-rc1', + VERSION = 'v0.7.7', /** Key for the Custom Config's version (librechat.yaml). */ CONFIG_VERSION = '1.2.1', /** Standard value for the first message's `parentMessageId` value, to indicate no parent exists. */
packages/mcp/package.json+1 −1 modified@@ -1,6 +1,6 @@ { "name": "librechat-mcp", - "version": "1.0.0", + "version": "1.1.0", "type": "module", "description": "MCP services for LibreChat", "main": "dist/index.js",
packages/mcp/src/connection.ts+6 −2 modified@@ -45,7 +45,11 @@ export class MCPConnection extends EventEmitter { iconPath?: string; timeout?: number; - constructor(serverName: string, private readonly options: t.MCPOptions, private logger?: Logger) { + constructor( + serverName: string, + private readonly options: t.MCPOptions, + private logger?: Logger, + ) { super(); this.serverName = serverName; this.logger = logger; @@ -54,7 +58,7 @@ export class MCPConnection extends EventEmitter { this.client = new Client( { name: 'librechat-mcp-client', - version: '1.0.0', + version: '1.1.0', }, { capabilities: {},
Vulnerability mechanics
Root cause
"The API keys management endpoint incorrectly processes user-supplied data, allowing it to overwrite existing user records."
Attack vector
An attacker must first authenticate to the application to obtain a valid JWT token. Then, the attacker sends a PUT request to the `/api/keys` endpoint. The request body includes a `userId` parameter, which overrides the authenticated user's ID. This allows the attacker to specify a victim's `userId` and inject their own API key details, effectively replacing the victim's configuration [ref_id=1].
Affected code
The vulnerability resides in the `api/server/routes/keys.js` file, specifically within the `PUT /api/keys` route handler. The code uses `await updateUserKey({ userId: req.user.id, ...req.body });`, where the spread operator `...req.body` allows for the injection of a malicious `userId` [ref_id=1].
What the fix does
The patch modifies the API key update logic to explicitly destructure only the expected fields (`name`, `value`, `expiresAt`) from the request body, rather than using the spread operator. This prevents the `userId` from being overwritten by the request body, ensuring that API keys are only updated for the authenticated user [patch_id=4549444]. The advisory also notes that the vulnerability is fixed in version 0.8.3-rc1.
Preconditions
- authThe attacker must be an authenticated user with a valid JWT token.
Generated on Jun 2, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
1News mentions
0No linked articles in our index yet.