Aug 26, 2026·6 min read·2 visits
Unauthenticated remote account takeover via federated login using unverified email claims in the AshAuthentication Elixir library.
An authentication bypass and account takeover vulnerability in the AshAuthentication Elixir library (developed by team-alembic) allows unauthenticated remote attackers to compromise local accounts. By relying on mutable and unverified email claims instead of stable cryptographic issuer and subject pairings during OAuth2 and OIDC federated login flows, the application fails to validate the trust boundary of the incoming session.
The ash_authentication library is a critical component within the Elixir ecosystem, facilitating secure registration, sign-in, and session management for Ash-based applications. It abstracts integration with third-party federated identity systems through standard OAuth2 and OpenID Connect (OIDC) protocols. This abstraction minimizes custom implementation logic but introduces strict dependencies on the configuration of federated mappings.
In affected versions, the library allows identity resolving mechanisms to bypass proper cryptographic identifier mapping. Instead of requiring structured mapping using the standard issuer and subject identifiers, the identity verification process falls back to testing and matching user records directly through mutable claims like email addresses. This configuration default widens the exposed attack surface.
The vulnerability is categorized under CWE-290 (Authentication Bypass by Spoofing). It poses a direct threat to application trust boundaries by permitting unauthenticated actors to bypass password challenges or secondary factor prompts when matching specific local email profiles.
The fundamental design weakness stems from a direct violation of the OpenID Connect Core specification. Section 5.7 explicitly mandates that the combination of the Issuer (iss) and Subject (sub) claims uniquely and stably identifies an end-user. Conversely, mutable attributes such as the email claim are explicitly declared unsafe for identity verification due to their susceptibility to re-assignment and spoofing.
In vulnerable versions of ash_authentication, the resolution logic failed to mandate an intermediate storage layer. This missing layer, the identity_resource, is responsible for mapping the unique provider identity (strategy, uid) to a local database user identifier. When this resource was omitted, the application fell back to looking up local users directly via incoming claim data.
Consequently, when an unauthenticated actor attempts to log in via an external OAuth provider that allows registering unverified email addresses, the provider issues a token containing the target victim's email. The target application consumes this claim, conducts a database query based solely on the email, matches the victim's record, and instantly initiates an active authenticated session without validating the origin identity.
The technical flaw exists in how OAuth2 callbacks are handled inside the identity change pipeline. Specifically, within Elixir.AshAuthentication.Strategy.OAuth2.IdentityChange, the user ID value was processed and assigned to changesets using dynamic key interpolation syntax.
# Vulnerable Syntax
UserIdentity.Actions.upsert(strategy.identity_resource, %{
user_info: Changeset.get_argument(changeset, :user_info),
oauth_tokens: Changeset.get_argument(changeset, :oauth_tokens),
strategy: Strategy.name(strategy),
"#{user_id_attribute_name}": user.id
})The syntax "#{user_id_attribute_name}": evaluates the dynamic key as a String type in Elixir. However, the Ash Framework database layers rely on Atom keys to bind attributes to model schemas. When evaluated as a string, the framework fails to resolve this parameter as a valid foreign key, preventing proper persistence of the identity record.
The patch replaces this structure using native Elixir map-arrow syntax to maintain dynamic key types:
# Patched Syntax
UserIdentity.Actions.upsert(
strategy.identity_resource,
%{
user_id_attribute_name => user.id,
user_info: Changeset.get_argument(changeset, :user_info),
oauth_tokens: Changeset.get_argument(changeset, :oauth_tokens),
strategy: Strategy.name(strategy)
},
opts
)By leveraging the user_id_attribute_name => user.id syntax, the dynamic key's structural type is correctly preserved as an Atom. This ensures the Ash data layer processes the database operation successfully, mapping the unique identity constraint without configuration loss.
Exploitation relies on an external identity provider that allows arbitrary email selection without strict ownership verification, or on administrative control over a custom OIDC server. An attacker targets an application known to run a vulnerable release of ash_authentication.
First, the attacker registers an account on the weak external identity provider using the email address of the victim's target local account. Second, the attacker visits the target application and initiates an authentication flow using the weak provider. The target application redirects the attacker to the provider for authorization.
Third, the provider returns an identity token verifying the user profile and transmitting the target email. The callback controller processes the token, queries the user database solely by the email claim, and finds the existing local account. The system registers a successful session, returning a valid authentication cookie or JSON Web Token representing the victim's profile to the attacker. This process is validated in the public proof-of-concept repository: https://github.com/Hunt-Benito/ash-authentication-oauth2-oidc-account-takeover-cve-2026-49757-email-based-user-matching.
A successful exploit results in total compromise of the confidentiality, integrity, and availability of the hijacked user account. If the target profile holds administrative privileges within the organization, the attacker obtains complete control over tenant resources, database schemas, and administrative panels.
The CVSS 4.0 base score is calculated at 9.2 (Critical), with vector CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N. This score reflects that network exposure is direct and requires no privileges or user interaction. The attack requirements parameter is flagged as present, as exploitation is contingent on the victim's email being registered inside the target database and the target app accepting federated logins from a weak provider.
While active exploitation has not been observed in wild campaigns, the exposure of applications using generic OIDC providers remains serious. System administrators must assume that any configuration allowing generic, unverified provider integrations has a highly critical exploit exposure risk.
Remediation requires upgrading the library and enforcing strict configuration limits. Developers must update their dependencies to 4.14.0 or higher (for the 4.x release line) or 5.0.0-rc.10 or higher (for the 5.x release line).
The patch changes the identity_resource from an optional parameters set to a strictly required parameter. To prevent connection failures, developers must create a user identity schema defining the unique mapping between user accounts and external identifiers. The database must then be migrated using mix ash.codegen and mix ash.migrate to enforce unique indexing across the (strategy, uid) fields.
Additionally, applications must configure verification trust flags. Specifically, setting trust_email_verified? to false prevents automatic email mapping from untrusted identity providers. The optional on_untrusted_email_match parameter can be configured to :reject or :confirm to require out-of-band validation via secure email verification links before federating accounts.
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
ash_authentication team-alembic | >= 0.1.0, < 4.14.0 | 4.14.0 |
ash_authentication team-alembic | >= 5.0.0-rc.0, < 5.0.0-rc.10 | 5.0.0-rc.10 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-290 |
| Attack Vector | Network (AV:N) |
| CVSS v4.0 | 9.2 (Critical) |
| Exploit Status | Proof of Concept Available |
| Impact | Authentication Bypass / Account Takeover |
| EPSS Score | 0.00615 |
| CISA KEV Status | Not Listed |
The software receives input from an untrusted source and trusts that input as an assertion of a local user's identity without performing sufficient validation.
A cryptographic validation flaw (CWE-345) exists in the built-in SCTP implementation of mediasoup (NPM package < 3.20.6, Rust crate < 0.22.5). Due to missing cryptographic signature verification of State Cookies, an on-path attacker targeting PlainTransport or PipeTransport without DTLS can forge state cookies containing static magic bytes. This allows the attacker to establish arbitrary SCTP associations and inject malicious DataChannel messages.
A critical logical flaw in the eml_parser Python module prior to version 3.0.2 allows malicious URLs to evade automated security analysis pipelines. By encoding key URI delimiter characters as HTML decimal entities, an attacker can mask indicators of compromise. Security controls, orchestration layers, and sandbox systems fail to detect these links, while downstream Mail User Agents natively reconstruct the malicious hyper-references when processed by end-users. This mechanism undermines the integrity of automated indicator extraction processes within Security Operations Centers.
A denial of service vulnerability in GOVCERT-LU eml_parser before version 3.0.2 allows unauthenticated remote attackers to trigger an unhandled RecursionError exception. The issue arises during the parsing of structured email headers containing excessively nested parentheses representing Comments and Folding White Space (CFWS). Because the parser fails to catch this recursion-limit exception from Python's standard library, processing of the entire mail immediately aborts, which can disrupt automated security triage pipelines and email ingestion components.
Prior to version 3.0.2, GOVCERT-LU's eml_parser library is vulnerable to an algorithmic complexity Denial of Service (DoS) vulnerability via the comment-stripping routine noparenthesis() in routing.py. An unauthenticated attacker can submit a crafted EML file containing nested parenthesized comments to cause complete CPU saturation. This happens due to a quadratic time complexity bottleneck in regex replacement of nested structures.
Whistle prior to version 2.10.3 contains a path traversal vulnerability in its internal service layer. An unauthenticated remote attacker can read arbitrary files on the hosting operating system by issuing a crafted GET request containing relative or absolute file paths to the `/cgi-bin/temp/get` endpoint. This behavior occurs because the application fails open when an input file parameter does not match the temporary file format regex.
An arbitrary file read and write vulnerability exists in the Model Context Protocol (MCP) server endpoints of sublinear-time-solver and consciousness-explorer. By providing unvalidated file paths to the export_state, import_state, saveVectorToFile, and loadVectorFromFile tools, local attackers can read or overwrite sensitive host files.