[PR #7326] fix(api-key): exclude userId from update data in validateApiKey function #7230

Open
opened 2026-03-13 13:29:03 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/7326
Author: @evnydd0sf
Created: 1/13/2026
Status: 🔄 Open

Base: canary ← Head: canary


📝 Commits (3)

  • 656a121 fix(api-key): exclude userId from updated API key object in validation
  • 1588b0a fix(api-key): exclude userId from update data in validateApiKey function
  • 3e7d116 docs: clarify intent of excluding immutable identifiers from updateData in validateApiKey function

📊 Changes

1 file changed (+8 additions, -5 deletions)

View changed files

📝 packages/better-auth/src/plugins/api-key/routes/verify-api-key.ts (+8 -5)

📄 Description

Background / Problem

When using Better Auth’s API Key plugin with the MongoDB adapter, we observed a data type corruption issue on the apikey.userId field:

  • API keys created through the official server API were stored with userId as a MongoDB ObjectId in our collection.
  • After calling auth.api.verifyApiKey (POST /api-key/verify) once, the same record’s userId was persisted back as a string.
  • This breaks downstream queries/aggregations that rely on ObjectId matching (e.g. listing/filtering by user via new ObjectId(userId)), causing “not found” results even though the data exists.

Root cause: verifyApiKey updates API key usage/rate-limit fields by writing back an object derived from the previously fetched API key record. The MongoDB adapter converts referenced IDs to strings on output, and during update it does not coerce those strings back to ObjectId. As a result, the update operation accidentally overwrites userId with its string representation.

Fix / Approach

This PR applies a minimal, targeted fix in the API key verification flow:

  • Keep verifyApiKey behavior the same (still updates usage/rate-limit fields like lastRequest, requestCount, remaining, updatedAt, etc.).
  • Explicitly exclude userId from the database update payload used during validateApiKey/verifyApiKey so the verification write-back cannot overwrite the existing userId type in MongoDB.
  • The change is applied to both write paths:
    • storage === "database"
    • storage === "secondary-storage" && fallbackToDatabase

Scope / Impact

  • Only affects the database update payload during API key verification.
  • Does not change validation results or rate limiting semantics.
  • Does not automatically migrate/repair existing records that were already converted to strings (those require a separate data fix).

Reproduction (before fix)

  1. Create an API key and confirm apikey.userId is stored as ObjectId.
  2. Call POST /api-key/verify with that key.
  3. Observe the API key record: userId becomes a string after verification, and subsequent queries expecting ObjectId may fail.

After this fix, verification updates occur without mutating userId in the database.


Summary by cubic

Prevented userId from being overwritten during API key verification to avoid ObjectId → string corruption in MongoDB. This keeps verification updates while preserving identifier types.

  • Bug Fixes
    • Exclude userId (and id) from update payload in validateApiKey.
    • Applied to both database and secondary-storage fallback paths.
    • No change to validation/rate limiting; existing stringified records are not auto-fixed.

Written for commit 3e7d116543. Summary will update on new commits.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/7326 **Author:** [@evnydd0sf](https://github.com/evnydd0sf) **Created:** 1/13/2026 **Status:** 🔄 Open **Base:** `canary` ← **Head:** `canary` --- ### 📝 Commits (3) - [`656a121`](https://github.com/better-auth/better-auth/commit/656a121bd16839ea3b9b4c5329ec37db169dc21c) fix(api-key): exclude userId from updated API key object in validation - [`1588b0a`](https://github.com/better-auth/better-auth/commit/1588b0a4ee0a530514bfcdc9fa235a8969a6b524) fix(api-key): exclude userId from update data in validateApiKey function - [`3e7d116`](https://github.com/better-auth/better-auth/commit/3e7d1165438fd85e0a3b4e5d603817940ebb29e4) docs: clarify intent of excluding immutable identifiers from updateData in validateApiKey function ### 📊 Changes **1 file changed** (+8 additions, -5 deletions) <details> <summary>View changed files</summary> 📝 `packages/better-auth/src/plugins/api-key/routes/verify-api-key.ts` (+8 -5) </details> ### 📄 Description ## Background / Problem When using Better Auth’s API Key plugin with the MongoDB adapter, we observed a data type corruption issue on the `apikey.userId` field: - API keys created through the official server API were stored with `userId` as a MongoDB `ObjectId` in our collection. - After calling `auth.api.verifyApiKey` (`POST /api-key/verify`) once, the same record’s `userId` was persisted back as a **string**. - This breaks downstream queries/aggregations that rely on `ObjectId` matching (e.g. listing/filtering by user via `new ObjectId(userId)`), causing “not found” results even though the data exists. Root cause: `verifyApiKey` updates API key usage/rate-limit fields by writing back an object derived from the previously fetched API key record. The MongoDB adapter converts referenced IDs to strings on output, and during **update** it does not coerce those strings back to `ObjectId`. As a result, the update operation accidentally overwrites `userId` with its string representation. ## Fix / Approach This PR applies a minimal, targeted fix in the API key verification flow: - Keep `verifyApiKey` behavior the same (still updates usage/rate-limit fields like `lastRequest`, `requestCount`, `remaining`, `updatedAt`, etc.). - Explicitly **exclude `userId`** from the database update payload used during `validateApiKey`/`verifyApiKey` so the verification write-back cannot overwrite the existing `userId` type in MongoDB. - The change is applied to both write paths: - `storage === "database"` - `storage === "secondary-storage" && fallbackToDatabase` ## Scope / Impact - Only affects the database update payload during API key verification. - Does not change validation results or rate limiting semantics. - Does not automatically migrate/repair existing records that were already converted to strings (those require a separate data fix). ## Reproduction (before fix) 1. Create an API key and confirm `apikey.userId` is stored as `ObjectId`. 2. Call `POST /api-key/verify` with that key. 3. Observe the API key record: `userId` becomes a string after verification, and subsequent queries expecting `ObjectId` may fail. After this fix, verification updates occur without mutating `userId` in the database. <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Prevented userId from being overwritten during API key verification to avoid ObjectId → string corruption in MongoDB. This keeps verification updates while preserving identifier types. - **Bug Fixes** - Exclude userId (and id) from update payload in validateApiKey. - Applied to both database and secondary-storage fallback paths. - No change to validation/rate limiting; existing stringified records are not auto-fixed. <sup>Written for commit 3e7d1165438fd85e0a3b4e5d603817940ebb29e4. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-03-13 13:29:03 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#7230