Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-45337

CVE-2026-45337: Better Auth Authentication Bypass Flaw

CVE-2026-45337 is an authentication bypass flaw in Better Auth's deviceAuthorization plugin that lets attackers hijack device authorization flows. This post covers technical details, affected versions, impact, and mitigation.

Published:

CVE-2026-45337 Overview

CVE-2026-45337 is an authorization bypass in the Better Auth TypeScript library affecting the deviceAuthorization plugin from version 1.6.0 up to 1.6.11. The plugin treats any authenticated session as the owner of a pending device code because GET /device does not claim the row, and POST /device/approve and POST /device/deny short-circuit when userId is unset. An authenticated attacker who learns a valid user_code can bind the polling device to the attacker's account or deny the legitimate device flow. The issue is fixed in version 1.6.11 and is categorized under CWE-285: Improper Authorization.

Critical Impact

An authenticated attacker can hijack a victim's device authorization flow, binding the polling device to the attacker-controlled account or blocking legitimate sign-in.

Affected Products

  • Better Auth versions 1.6.0 through 1.6.10
  • Applications using the deviceAuthorization plugin
  • Fixed in Better Auth version 1.6.11

Discovery Timeline

  • 2026-07-15 - CVE-2026-45337 published to the National Vulnerability Database (NVD)
  • 2026-07-15 - Last updated in NVD database

Technical Details for CVE-2026-45337

Vulnerability Analysis

The vulnerability resides in the OAuth 2.0 Device Authorization Grant implementation within the Better Auth deviceAuthorization plugin. In a correct implementation, the verifying user's session must be bound to the device code row when the user retrieves the code, so subsequent approval or denial calls are authorized only for that user. Better Auth stored device code records without a userId binding at creation, and the verification endpoint GET /device never claimed the row for the calling session. When a client called POST /device/approve or POST /device/deny, the handler short-circuited on the missing userId and accepted the caller as the owner. Any authenticated user who obtains a valid user_code can therefore act as the verifier for another user's device.

Root Cause

The root cause is missing session-to-resource binding on the device code record. The pending device code row is created with no userId field, and no state transition claims ownership when a signed-in user visits the verification page. Downstream endpoints treat the absence of userId as an implicit authorization to the caller rather than an error.

Attack Vector

Exploitation requires the attacker to authenticate to the target application and obtain a legitimate user_code, which is typically shown to a user on a secondary device such as a TV or CLI. The attacker submits that user_code to POST /device/approve, causing the polling device to receive tokens minted for the attacker's account. Alternatively, the attacker submits POST /device/deny to disrupt the victim's sign-in. User interaction is required because the attacker must acquire the short-lived user_code.

typescript
// Patch: bind device authorization to the verifier session
// packages/better-auth/src/plugins/device-authorization/routes.ts
            data: {
                deviceCode,
                userCode,
+               userId: null,
                expiresAt,
                status: "pending",
                pollingInterval: ms(opts.interval),

Source: GitHub commit 99a254a

typescript
// Patch: new error code enforcing claim before approve/deny
// packages/better-auth/src/plugins/device-authorization/error-codes.ts
    ACCESS_DENIED: "Access denied",
    INVALID_USER_CODE: "Invalid user code",
    DEVICE_CODE_ALREADY_PROCESSED: "Device code already processed",
+   DEVICE_CODE_NOT_CLAIMED:
+       "Device code has not been claimed by a verifying session; call `GET /device` with the `user_code` while signed in before approving or denying",
    POLLING_TOO_FREQUENTLY: "Polling too frequently",
    USER_NOT_FOUND: "User not found",
    FAILED_TO_CREATE_SESSION: "Failed to create session",

Source: GitHub commit 99a254a

Detection Methods for CVE-2026-45337

Indicators of Compromise

  • Successful POST /device/approve or POST /device/deny requests where the calling session's userId differs from the account that later receives tokens.
  • Unexpected active sessions or refresh tokens created immediately after device authorization completions.
  • Repeated GET /device submissions with brute-force patterns targeting the user_code parameter.

Detection Strategies

  • Audit application logs for device authorization approvals that are not preceded by a GET /device claim from the same session.
  • Correlate the session identifier of the approving request with the session that ultimately polls /token and receives credentials.
  • Alert on deviceAuthorization events where user_code submissions originate from IPs or user agents that differ from the polling device.

Monitoring Recommendations

  • Log all deviceAuthorization plugin endpoints with session ID, user ID, user_code hash, IP, and user agent.
  • Track the ratio of denied to approved device codes per account to detect denial-of-flow abuse.
  • Monitor for accounts that approve device codes for services they do not typically use.

How to Mitigate CVE-2026-45337

Immediate Actions Required

  • Upgrade the better-auth package to version 1.6.11 or later in all applications using the deviceAuthorization plugin.
  • Invalidate any pending device codes issued by vulnerable versions and force re-authentication for recently completed device flows.
  • Review audit logs for anomalous POST /device/approve and POST /device/deny activity dating back to the deployment of Better Auth 1.6.0.

Patch Information

The fix is available in Better Auth v1.6.11. The patch, delivered in Pull Request #9573 and commit 99a254a, initializes device code rows with userId: null, claims the row to the verifying session in GET /device, and introduces the DEVICE_CODE_NOT_CLAIMED error to block approve and deny before a claim occurs. See the GitHub Security Advisory GHSA-cq3f-vc6p-68fh for the complete disclosure.

Workarounds

  • Disable the deviceAuthorization plugin until the upgrade to 1.6.11 is deployed.
  • Restrict access to /device, /device/approve, and /device/deny behind additional session validation that verifies the calling user matches the intended verifier.
  • Shorten user_code and device code lifetimes to reduce the exploitation window when the plugin cannot be immediately disabled.
bash
# Upgrade Better Auth to the patched release
npm install better-auth@1.6.11
# or
pnpm add better-auth@1.6.11
# or
yarn add better-auth@1.6.11

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.