CVE-2025-61928 Overview
CVE-2025-61928 is a critical authentication bypass vulnerability in Better Auth, an authentication and authorization library for TypeScript. In versions prior to 1.3.26, unauthenticated attackers can create or modify API keys for any user by passing that user's ID in the request body to the api/auth/api-key/create route.
The vulnerability stems from flawed session validation logic where, when no session exists but userId is present in the request body, the authRequired flag becomes false and the user object is set to the attacker-controlled ID. This allows attackers to bypass authentication entirely and generate API keys for arbitrary users, enabling complete account takeover.
Critical Impact
Unauthenticated attackers can generate API keys for any user and immediately gain complete authenticated access, allowing them to perform any action as the victim user and potentially compromise user data and the application.
Affected Products
- Better Auth versions prior to 1.3.26
- Applications using the Better Auth API key plugin with client-facing endpoints
- TypeScript/JavaScript applications implementing Better Auth for authentication
Discovery Timeline
- October 9, 2025 - CVE-2025-61928 published to NVD
- October 14, 2025 - Last updated in NVD database
Technical Details for CVE-2025-61928
Vulnerability Analysis
This authentication bypass vulnerability exists in the API key creation and update endpoints of the Better Auth library. The core issue lies in the conditional logic that determines whether authentication is required for a request.
The vulnerable code path evaluates: session?.user ?? (authRequired ? null : { id: ctx.body.userId }). When an attacker sends a request without a valid session but includes a userId parameter in the request body, the authRequired variable is incorrectly set to false. This causes the system to accept the attacker-supplied userId as legitimate, creating a user object from attacker-controlled input.
Additionally, server-only field validation, which normally prevents clients from setting privileged fields, only executes when authRequired is true (lines 280-295). By exploiting this bypass, attackers can set privileged fields that should only be accessible to server-side operations.
Root Cause
The root cause is improper authorization validation (CWE-285) in the API key creation logic. The code incorrectly determines authentication requirements based on the presence of userId in the request body rather than properly validating the session state. This design flaw allows the authRequired flag to be manipulated by including a userId parameter, completely bypassing the authentication check.
Attack Vector
An attacker can exploit this vulnerability remotely without any authentication by sending a crafted HTTP POST request to the api/auth/api-key/create endpoint. The attack requires knowledge of a target user's ID, which may be obtainable through enumeration or information disclosure. The same vulnerability pattern exists in the update endpoint, allowing modification of existing API keys.
The attack flow:
- Attacker identifies a target user's ID
- Attacker sends a POST request to /api/auth/api-key/create with the victim's userId in the request body
- The server creates an API key for the victim user
- Attacker uses the generated API key to authenticate as the victim
} = ctx.body;
const session = await getSessionFromCtx(ctx);
- const authRequired = (ctx.request || ctx.headers) && !ctx.body.userId;
+ const authRequired = ctx.request || ctx.headers;
const user =
- session?.user ?? (authRequired ? null : { id: ctx.body.userId });
+ authRequired && !session
+ ? null
+ : session?.user || { id: ctx.body.userId };
+
if (!user?.id) {
throw new APIError("UNAUTHORIZED", {
message: ERROR_CODES.UNAUTHORIZED_SESSION,
});
}
+ if (session && ctx.body.userId && session?.user.id !== ctx.body.userId) {
+ throw new APIError("UNAUTHORIZED", {
+ message: ERROR_CODES.UNAUTHORIZED_SESSION,
+ });
+ }
+
if (authRequired) {
// if this endpoint was being called from the client,
// we must make sure they can't use server-only properties.
Source: GitHub Commit for Better-Auth
Detection Methods for CVE-2025-61928
Indicators of Compromise
- Unexpected API key creation events in authentication logs for users who did not initiate them
- POST requests to /api/auth/api-key/create containing userId parameters without valid session cookies
- Multiple API key creation attempts from single IP addresses targeting different user IDs
- Authentication events using newly created API keys from unfamiliar IP addresses or locations
Detection Strategies
- Monitor authentication logs for API key creation requests that lack valid session authentication
- Implement anomaly detection for sudden spikes in API key generation across multiple user accounts
- Alert on API key usage patterns that deviate from established user behavior baselines
- Review web application firewall logs for requests to API key endpoints with unusual parameters
Monitoring Recommendations
- Enable detailed logging for all Better Auth API key operations including request parameters and session state
- Set up real-time alerting for unauthenticated or suspicious API key creation attempts
- Implement user notification mechanisms for API key creation and usage events
- Regularly audit existing API keys for unauthorized or suspicious entries
How to Mitigate CVE-2025-61928
Immediate Actions Required
- Upgrade Better Auth to version 1.3.26 or later immediately
- Audit all existing API keys created in the application for unauthorized entries
- Revoke any API keys that were created without legitimate user sessions
- Review application logs for potential exploitation attempts targeting the vulnerable endpoints
Patch Information
The vulnerability has been addressed in Better Auth version 1.3.26. The fix modifies the authentication logic to properly validate sessions regardless of request parameters. The patch ensures that:
- The authRequired flag is determined solely by the presence of a request context, not by userId presence
- A proper session must exist for authenticated operations
- If a session exists but the userId in the body doesn't match the session user, the request is rejected
For technical details on the patch, refer to the GitHub Commit for Better-Auth and the GitHub Security Advisory GHSA-99h5-pjcv-gr6v.
Workarounds
- Temporarily disable or restrict access to the API key creation and update endpoints at the network level
- Implement additional middleware to validate session authentication before requests reach Better Auth endpoints
- Use network-level controls (WAF rules) to block unauthenticated requests containing userId parameters to API key endpoints
# Example: Block unauthenticated API key creation at reverse proxy level
# Nginx configuration to require authentication header for API key endpoints
location /api/auth/api-key/ {
if ($http_authorization = '') {
return 401;
}
proxy_pass http://backend;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


