# IDOR via `userId` Override in PUT /api/keys Allows Overwriting Any User's API Keys ## meta platform: huntr program: LibreChat asset: https://github.com/danny-avila/LibreChat date: 2026-02-12 status: DRAFT ```` Repository URL: https://github.com/danny-avila/LibreChat Package Manager: npm Version Affected: v0.8.2 Vulnerability Type: Authorization Bypass Through User-Controlled Key CVSS: - Attack Vector: Network - Attack Complexity: Low - Privileges Required: Low - User Interaction: None - Scope: Unchanged - Confidentiality: None - Integrity: High - Availability: Low Title: IDOR via userId override in PUT /api/keys allows overwriting any user's API keys Description: # Description The `PUT /api/keys` endpoint in LibreChat allows any authenticated user to overwrite another user's stored API keys. In `api/server/routes/keys.js` line 8, the request body is spread after the server-set userId: await updateUserKey({ userId: req.user.id, ...req.body }); Because JavaScript object spread overwrites earlier properties with later ones, a `userId` field in the request body replaces `req.user.id`. The downstream `updateUserKey()` function in `packages/data-schemas/src/methods/key.ts` uses this attacker-controlled `userId` in a `findOneAndUpdate({ userId, name }, ...)` call with `upsert: true`, directly writing to the victim's key document. The DELETE and GET handlers on the same file are NOT vulnerable — they use explicit destructuring and never spread user input. # Proof of Concept ## Prerequisites - LibreChat instance with two registered users - Attacker has a valid JWT token - Victim's MongoDB ObjectID (userId) is known ## Steps 1. Authenticate as the attacker and obtain the JWT from the `token` cookie. 2. Send a PUT request with a `userId` field targeting the victim: ```bash curl -s -X PUT "https://TARGET/api/keys" \ -H "Content-Type: application/json" \ -H "Cookie: token=ATTACKER_JWT" \ -d '{ "userId": "VICTIM_MONGODB_OBJECTID", "name": "openAI", "value": "sk-attacker-controlled-key" }' Impact: This vulnerability is capable of allowing any authenticated user to overwrite any other user's stored API keys (OpenAI, Anthropic, Azure, Google, Bedrock) by injecting an arbitrary userId into the PUT /api/keys request body. This enables denial of service by invalidating victims' keys, billing abuse by replacing keys with attacker-controlled ones, and conversation interception through attacker-monitored API keys. Occurrences: - Permalink: https://github.com/danny-avila/LibreChat/blob/cc7f61096be47ab2cd4e155bd44c18350f027f05/api/server/routes/keys.js#L7-L10 Description: PUT handler spreads `req.body` after `userId`, allowing client to override server-set `userId` with an arbitrary value. - Permalink: https://github.com/danny-avila/LibreChat/blob/cc7f61096be47ab2cd4e155bd44c18350f027f05/packages/data-schemas/src/methods/key.ts#L99-L125 Description: `updateUserKey()` uses attacker-controlled `userId` in `findOneAndUpdate({ userId, name }, ...)` query with `upsert: true`, writing to any user's key store. References: - https://cwe.mitre.org/data/definitions/639.html — CWE-639: Authorization Bypass Through User-Controlled Key - https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/ — OWASP API1:2023 Broken Object Level Authorization - https://cwe.mitre.org/data/definitions/915.html — CWE-915: Mass Assignment ````