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

CVE-2026-65633: AshAuthentication JWT Auth Bypass Vulnerability

CVE-2026-65633 is an authentication bypass flaw in team-alembic AshAuthentication that allows purpose-limited JWTs to be replayed as full bearer API credentials. This post explains its impact, affected versions, and mitigation steps.

Published:

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

Sources: National Vulnerability Database, CISA KEV, Exploit-DB

CVE-2026-65633 Overview

CVE-2026-65633 is an improper authentication vulnerability [CWE-287] in the team-alembic ash_authentication library for Elixir. The bearer-token helper AshAuthentication.Plug.Helpers.retrieve_from_bearer/3 verifies JWT signatures and rejects tokens containing an act claim, but does not check that the token's purpose claim equals user at the bearer boundary. Purpose-limited JWTs, such as the sign_in token issued by WebAuthn and the Password strategy, can be replayed directly in an Authorization: Bearer header and resolve to a full current_user assignment. The flaw affects ash_authentication from 3.10.5 before 4.14.2 and from 5.0.0-rc.0 before 5.0.0-rc.13.

Critical Impact

An attacker who obtains a not-yet-exchanged sign_in token can authenticate as the target subject, bypassing the library's one-time-use and revocation contract.

Affected Products

  • team-alembic ash_authentication 3.10.5 through versions before 4.14.2
  • team-alembic ash_authentication 5.0.0-rc.0 through versions before 5.0.0-rc.13
  • Applications using WebAuthn or the Password strategy with sign_in_tokens_enabled?: true and require_token_presence_for_authentication?: false

Discovery Timeline

  • 2026-08-25 - CVE-2026-65633 published to NVD
  • 2026-08-25 - Last updated in NVD database

Technical Details for CVE-2026-65633

Vulnerability Analysis

The ash_authentication library issues purpose-scoped JWTs for narrow flows. The sign_in token, emitted by WebAuthn and the Password strategy, is intended to be exchanged exactly once through a preparation that validates the purpose claim and revokes the token. The stateless bearer path never enforces this contract.

retrieve_from_bearer/3 calls Jwt.verify/3 and rejects tokens carrying an act claim, but performs no purpose check. When the resource is configured with require_token_presence_for_authentication?: false (the DSL default), the follow-on validate_token/3 returns {:ok, nil} without consulting the stored token record. No downstream code enforces purpose == "user", so a sign_in token is accepted as a general-purpose bearer credential.

Root Cause

The root cause is missing purpose-scope validation at the bearer authentication boundary. The library treats a valid JWT signature and absence of the act claim as sufficient for bearer authentication, conflating narrow, purpose-limited tokens with full user-session credentials. The session-based path authenticate_resource_from_session/4 and configurations with require_token_presence_for_authentication?: true correctly enforce the purpose claim against the token resource and are not affected.

Attack Vector

An attacker must obtain a still-valid, not-yet-exchanged sign_in token for the target subject. Realistic exposure paths include referrer or log leakage of magic-link URLs, interception of magic-link delivery channels, or a partially compromised intermediary. The attacker submits the captured token as Authorization: Bearer <token> to any route wired to retrieve_from_bearer/3, and the request resolves as the target user.

text
     |> Enum.reduce(conn, fn token, conn ->
       with {:ok, %{"sub" => subject, "jti" => jti} = claims, resource}
            when not is_map_key(claims, "act") <- Jwt.verify(token, otp_app, opts),
+           true <- usable_as_bearer_token?(claims),
            {:ok, token_record} <-
              validate_token(resource, jti, opts),
            {:ok, user} <-

Source: GitHub Commit 124eddd1. The patch inserts a usable_as_bearer_token?/1 guard that rejects tokens whose purpose claim is not user before validate_token/3 is called.

Detect Identity Attacks the Moment Authentication Fails

Singularity™ Identity surfaces credential misuse, lateral movement, and privilege escalation in real time, so you can contain the breach before it spreads.

Stop Identity Attacks

Detection Methods for CVE-2026-65633

Indicators of Compromise

  • Successful authenticated requests where the presented JWT carries a purpose claim other than user (for example sign_in).
  • Repeated presentation of the same jti value across multiple bearer requests, indicating replay of a one-time token.
  • Bearer authentications for a subject that lack a corresponding session-establishment event or token-exchange record.

Detection Strategies

  • Decode inbound JWTs at the reverse proxy or application logger and alert on any purpose value other than user reaching bearer-protected routes.
  • Correlate jti values in application logs against the stored token resource to detect tokens presented after they should have been revoked.
  • Audit application routing to enumerate every plug that invokes retrieve_from_bearer/3 and confirm the associated resource configuration.

Monitoring Recommendations

  • Log full JWT claim sets (excluding signatures) for bearer authentications during the remediation window.
  • Alert on magic-link URLs appearing in HTTP referrer headers, web server access logs, or outbound proxy logs.
  • Monitor for unexpected access from IP addresses or user agents that do not match the target user's normal session pattern.

How to Mitigate CVE-2026-65633

Immediate Actions Required

  • Upgrade ash_authentication to 4.14.2 or 5.0.0-rc.13 or later.
  • Set require_token_presence_for_authentication?: true on any resource exposed through retrieve_from_bearer/3 until the upgrade is complete.
  • Revoke any outstanding sign_in tokens by clearing the token resource, forcing re-authentication.
  • Rotate JWT signing secrets if sign_in tokens may have been exposed through logs, referrers, or intercepted delivery channels.

Patch Information

The fix is delivered in ash_authentication versions 4.14.2 and 5.0.0-rc.13. The commits 124eddd1 and 8cf8b2d4 add a usable_as_bearer_token?/1 guard in lib/ash_authentication/plug/helpers.ex that rejects any JWT whose purpose claim is not user before the bearer path returns a current_user. See the GitHub Security Advisory GHSA-6vcj-3h59-rrc3 and the CNA advisory for the full disclosure.

Workarounds

  • Set require_token_presence_for_authentication?: true on affected resources so the token resource is consulted and purpose == "user" is enforced.
  • Prefer the session-based path authenticate_resource_from_session/4, which is not affected.
  • Disable sign_in_tokens_enabled? on the Password strategy where it is not required, and restrict WebAuthn flows to trusted transport channels.
bash
# Configuration example - enforce token presence on affected resources
# In your Ash resource module:
#
#   authentication do
#     tokens do
#       enabled? true
#       require_token_presence_for_authentication? true
#     end
#   end
#
# Then upgrade the dependency in mix.exs:
#   {:ash_authentication, "~> 4.14.2"}
mix deps.update ash_authentication
mix compile --force

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

Sources: National Vulnerability Database, CISA KEV, Exploit-DB

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.