CVE-2026-53518
JavaScript vulnerability analysis and mitigation

Overview

CVE-2026-53518 is a race condition vulnerability in the Better Auth TypeScript authentication library that allows concurrent redemption of single-use OAuth 2.0 authorization codes, enabling an attacker to obtain multiple independent token sets from a single authorization code. It affects @better-auth/oauth-provider versions >= 1.6.0 and < 1.6.11, as well as better-auth versions >= 1.4.8-beta.7 and < 1.6.11 when using the embedded oauth-provider, oidc-provider, or mcp plugins. The vulnerability was reported by @chdanielmueller, published to the GitHub Advisory Database on July 7, 2026, and assigned CVE-2026-53518. It carries a CVSS v3.1 base score of 8.1 (High) and a CVSS v4.0 base score of 7.6 (High) (Github Advisory, Security Advisory).

Technical details

The root cause is a non-atomic find-then-delete sequence (TOCTOU race condition, CWE-367; CWE-362) used to redeem single-use authorization codes at the POST /oauth2/token endpoint for the authorization_code grant. When two concurrent HTTP requests arrive with the same authorization code, both pass the findVerificationValue read step before either deleteVerificationByIdentifier call completes, causing both requests to proceed through PKCE verification and token minting — violating RFC 6749 §4.1.2's single-use requirement. The same vulnerable primitive was shared across the @better-auth/oauth-provider token endpoint and the legacy /oauth2/token and /mcp/token paths in the oidc-provider and mcp plugins. Additionally, the deletion primitive discarded the row count returned by adapter.deleteMany, making it impossible for any call site to detect that another caller had already claimed the row (CWE-294) (Security Advisory, Patch Commit).

Impact

Successful exploitation results in multiple independent token sets — access tokens, refresh tokens, and ID tokens — being minted from a single authorization code, all valid for the original user's authorization scope. An attacker who intercepts or races a legitimate user's authorization code exchange can obtain their own valid credential set, effectively impersonating the user and gaining unauthorized access to any protected resources the user is authorized to access. Standard OAuth single-use enforcement does not fire for the second redemption when both requests interleave through the read step, meaning the attack bypasses detection by the authorization server. The impact extends to all deployments using the affected oidc-provider and mcp plugins, including MCP clients such as Claude Desktop and custom AI agents (Security Advisory).

Exploitability

No public proof-of-concept exploit code is known to exist, and there is no evidence of in-the-wild exploitation at this time (Feedly). The vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. The EPSS score is approximately 0.23% (14th percentile), indicating a low near-term exploitation probability. Exploitation requires user interaction — a legitimate user must first complete the authorization flow to generate a valid code — but no privileges are required on the attacker's part, and the attack complexity is low once a code is obtained (Github Advisory).

Exploitation steps

  1. Obtain a valid authorization code: The attacker must first obtain a legitimate authorization code issued to a victim user. This could be achieved via a malicious redirect URI (if the client is misconfigured), network interception, or by being the legitimate user themselves attempting to exploit the race for a second session.
  2. Prepare concurrent token exchange requests: Craft two identical POST /oauth2/token (or /api/auth/oauth2/token) requests with grant_type=authorization_code, the captured code, valid client_id, client_secret (for confidential clients), redirect_uri, and PKCE code_verifier if applicable.
  3. Race the token endpoint: Send both requests simultaneously (e.g., using Promise.all in JavaScript, or parallel curl invocations) so that both arrive at the server before either deleteVerificationByIdentifier call completes. The timing window exists at each await boundary in the async handler.
  4. Collect forked token sets: Both requests pass the findVerificationValue read step and proceed to mint independent access tokens, refresh tokens, and ID tokens. The attacker retains the second token set while the legitimate user receives the first.
  5. Access protected resources: Use the attacker-controlled token set to authenticate as the victim user against any resource server that accepts tokens issued by the vulnerable Better Auth instance (Security Advisory, Patch Commit).

Indicators of compromise

  • Network: Two near-simultaneous POST requests to /api/auth/oauth2/token, /oauth2/token, or /mcp/token with identical code parameter values originating from different source IPs or connections within milliseconds of each other.
  • Logs: Authorization server logs showing the same authorization code appearing in two successful token exchange responses (both returning access_token); absence of an invalid_grant error for the second redemption of a code in vulnerable versions.
  • Application/Database: Two oauthAccessToken rows in the database sharing the same upstream authorization code reference and issued within milliseconds of each other for the same user; duplicate refresh token entries linked to the same authorization event.
  • Behavioral: Unexpected active sessions or API activity for a user account occurring concurrently from different clients or IP addresses shortly after an OAuth authorization flow completes (Security Advisory).

Mitigation and workarounds

The definitive fix is to upgrade @better-auth/oauth-provider and better-auth to version 1.6.11 or later, which replaces the non-atomic find-then-delete sequence with an atomic internalAdapter.consumeVerificationValue primitive — the first concurrent caller receives the row and mints tokens, while subsequent racers receive null and return invalid_grant (v1.6.11 Release). If an immediate upgrade is not possible, partial mitigations include: deploying a reverse proxy (e.g., Envoy, NGINX with Lua, or a Redis-backed Cloudflare Worker) that serializes concurrent requests sharing the same code parameter; adding a database-level uniqueness constraint to prevent duplicate oauthAccessToken rows for the same authorization code; or wrapping deleteVerificationByIdentifier with a custom adapter hook that surfaces the delete count and rejects with invalid_grant when zero. None of these workarounds fully close the vulnerability without a code patch (Security Advisory).

Additional resources


SourceThis report was generated using AI

Related JavaScript vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-77415CRITICAL9.3
  • JavaScript logoJavaScript
  • jsonata
NoYesAug 21, 2026
CVE-2026-77414CRITICAL9.3
  • JavaScript logoJavaScript
  • jsonata
NoYesAug 21, 2026
CVE-2026-77413CRITICAL9.3
  • JavaScript logoJavaScript
  • jsonata
NoYesAug 21, 2026
CVE-2026-63421HIGH7.5
  • JavaScript logoJavaScript
  • @keystone-6/core
NoYesAug 21, 2026
CVE-2026-53509MEDIUM5.7
  • JavaScript logoJavaScript
  • @aborruso/ckan-mcp-server
NoYesAug 21, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management