Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessAuthenticate as a user of one tenant
-
DeliveryEnumerate or obtain another tenant's record id
-
ExploitCall upsert create action with that primary key
-
ExecutionRecord returned and upsert fields overwritten
-
PersistDefault upsert rewrites tenant attribute
-
ImpactCross-tenant record read and takeover
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V8 - Authorization Object-level authorization, IDOR prevention
|
| Exploitation Conditions | Requires a resource using attribute multitenancy that exposes to callers of one tenant a create action with upsert? true which either upserts on the primary key (no upsert_identity) and accepts that key, or upserts on an all_tenants? identity; the caller must be an authenticated user of a tenant (PR:L) and must know or be able to enumerate a record key belonging to another tenant (e.g. a serial integer id, or an id leaked via a shared link or export). Limiting factors: exploitation is impossible unless such an upsert action is exposed, read/update policies are bypassed only on the upsert path, and the attacker needs a valid foreign key (AT:P). The documented workaround is to add upsert_condition expr(<tenant attribute> == ^tenant()) to every affected create action and not combine it with return_skipped_upsert?; this does not protect the Mnesia data layer, which ignores upsert conditions in affected versions, so updating to 3.37.2 is the only complete fix. |
| Impact | This is a credible, action-worthy flaw rather than inflated severity. The supplied CVSS 4.0 vector (AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H) describes a network-reachable, low-complexity attack by a low-privileged (authenticated, PR:L) caller with a present attack requirement (AT:P) - the attacker must hold or enumerate another tenant's record key - yielding high confidentiality and integrity impact and no availability impact (VA:N), scored 7.6. The description substantiates the vector: a tenant user supplies a foreign primary key to an upserting create action, reads back all of that record's attributes (confidentiality), overwrites its upsert fields, and - with default upsert fields - rewrites the tenant attribute to move the record into their own tenant (integrity/takeover). The vuln.today decision label is 'this_week', consistent with a serious authorization bypass that is not under active exploitation. No KEV listing and no EPSS score are provided, and no working exploit code is supplied (only vendor fix commits), so there is no evidence of in-the-wild use; the weakness class (CWE-639, IDOR-style) and the note that keys may be serial integers or leak via shared links/exports mean exploitation is realistic wherever the preconditions hold. The AT:P requirement and PR:L authentication are the main factors keeping this below critical. No signals conflict; the chief unknowns are EPSS and real-world exposure of qualifying upsert actions. |
| Exploit ScenarioDerived | An authenticated user of Tenant A calls a create action with upsert? true that accepts the primary key, passing the id of a record owned by Tenant B. Because the upsert conflict is matched on the primary key (or an all_tenants? identity) without tenant scoping, the action returns all of Tenant B's record attributes to the attacker and overwrites the upsert fields, and with default upsert fields rewrites the tenant attribute so the record is moved into Tenant A. No public exploit code is provided, but the fix commits and advisory describe the mechanism precisely. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 26, 2026
Cross-tenant record takeover in the Ash framework (Elixir) for versions 1.22.0 up to 3.37.2: when a resource uses attribute multitenancy and exposes a create action with upsert? true that accepts the primary key (or upserts on an all_tenants? identity), an authenticated user of one tenant can supply another tenant's record ID and have that record updated, its full attribute set returned, and - with default upsert fields - its tenant attribute rewritten, moving the record into the attacker's tenant. Read and update policies do not run on the upsert path, and tenant-scoped create policies pass because the tenant on the request is the caller's own, so the only meaningful preconditions are that such an action is exposed and that the attacker knows or can enumerate a foreign key (for example a serial integer ID or an ID leaked through a shared link or export). The vendor has released a fix in ash 3.37.2; no public exploit code was identified at time of analysis, and the priority signal is to patch this week rather than an emergency response.
RemediationAI
Upgrade the ash dependency to 3.37.2, the vendor-released fix; the advisory states patched versions explicitly and this is the only complete remediation, including for the Mnesia data layer. If the upgrade cannot land immediately, the vendor-documented workaround is to add upsert_condition expr(<tenant attribute> == ^tenant()) to every create action that upserts on the primary key or on an all_tenants? identity, and to not combine that condition with return_skipped_upsert? - with this in place an upsert aimed at another tenant's record fails with Ash.Error.Changes.StaleRecord (or is skipped in a bulk create) and leaves the target record unchanged. Note the trade-off and the gap: this workaround does not help on the Mnesia data layer, which ignores upsert conditions in affected versions, so Mnesia-backed deployments must take the 3.37.2 upgrade; adding return_skipped_upsert? alongside the condition would also undermine the protection. As a secondary containment measure, remove or restrict upsert? true create actions that accept a caller-supplied primary key or that target an all_tenants? identity, since the flaw is only reachable through that action shape. References: fix commit https://github.com/ash-project/ash/commit/c9f0cdb31e7c084def05f3f5be69dd7bb7721754, advisory https://github.com/ash-project/ash/security/advisories/GHSA-vw7c-67pf-gh96.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
Ash is an Elixir application framework whose data layer abstraction supports multitenancy in two modes; this flaw is specific to attribute multitenancy, where a tenant is stored as a column on the row rather than a separate schema or database. In the affected range, Ash.Actions.Create (lib/ash/actions/create/create.ex) and Ash.Actions.Create.Bulk (lib/ash/actions/create/bulk.ex) performed an upsert on the primary key, or on an identity marked all_tenants?, without scoping the conflicting record lookup to the tenant of the incoming request. Because the conflict resolution is driven by an identifier supplied by the caller, this is a classic CWE-639 authorization bypass through a user-controlled key: the caller selects the row that the upsert will match against, and Ash then applies the upsert fields to that row. Two framework behaviors compound the impact - read and update policies are not evaluated on the upsert path, and tenant-scoped create policies still pass because the request's tenant is legitimate for the caller. With the default upsert field set, the tenant attribute itself is among the written attributes, so the record is reassigned to the attacker's tenant rather than merely modified, and the full attribute list of the matched record is returned to the caller, giving a read primitive as well. The fix in 3.37.2 addresses how the upsert conflict target is resolved relative to the request's tenant.
Know when Ash gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
Network-reachable call by an authenticated tenant user (PR:L), low complexity since foreign keys are often enumerable; cross-tenant read and takeover give C:H/I:H, no availability impact (A:N).
Primary rating from Vendor (EEF).
CVSS VectorVendor: EEF
DescriptionCVE.org
Authorization Bypass Through User-Controlled Key vulnerability in ash-project ash allows a user of one tenant to read, overwrite and take over another tenant's records via an upserting create action.
Under attribute multitenancy, Ash.Actions.Create (lib/ash/actions/create/create.ex) and Ash.Actions.Create.Bulk (lib/ash/actions/create/bulk.ex) upserted on the primary key, or on an all_tenants? identity, without scoping the conflicting record to the request's tenant. A caller of a create action with upsert? true that accepts the primary key, supplying a record id from another tenant, updated that record's upsert fields and received all of its attributes in the result. With the default upsert fields the tenant attribute was written too, moving the record into the caller's tenant. Read and update policies do not run for upserts, and tenant-scoped create policies pass because the tenant is the caller's own.
This issue affects ash: from 1.22.0 before 3.37.2.
Technical POC Analysis
CWE-639, authorization bypass through user-controlled key.
Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.
Executive ViewAI
A high-severity cross-tenant record takeover vulnerability in the Ash framework (Elixir) versions 1.22.0 to 3.37.2 allows an authenticated attacker to hijack records across tenants. This impacts organizations using Ash with attribute multitenancy, potentially compromising data integrity and confidentiality. Leadership must act promptly to patch affected applications and assess potential tenant data breaches.
Apply vendor patch.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Private argument injection in the Ash Elixir framework (versions 3.0.0 through 3.29.2) allows end users to set action ar
An issue was discovered in the ash crate before 0.33.1 for Rust. Rated critical severity (CVSS 9.8), this vulnerability
Atom table exhaustion in the Ash framework (Elixir) allows an unauthenticated remote attacker to crash a BEAM node by su
An authorization bypass in the Ash framework (Elixir) lets authenticated, lower-privileged actors recover values they ar
Information disclosure in the Ash framework for Elixir (versions 2.6.0 up to but not including 3.34.6) lets an authentic
An incorrect authorization flaw in the Elixir Ash framework (versions 3.24.0 up to but not including 3.37.1) lets an aut
Persistent record-level denial of service in the ash Elixir resource framework (versions 3.6.3-3.32.1) lets any actor wh
Integer overflow in Ash Framework's vector encoding corrupts stored vectors in any Elixir application using Ash versions
CPU exhaustion in Ash Framework's string type constraint handler allows denial of service against Elixir applications th
Memory exhaustion via decompression bomb in Ash Framework's keyset pagination can terminate Erlang nodes running version
Unbounded string storage in Ash Framework versions 0.10.0 through 3.32.x allows unauthenticated attackers to bypass max_
Memory exhaustion in Ash Framework's runtime filter engine allows an attacker controlling filter inputs to crash an Elix
EUVD-2026-109637
NVD
CVE.org
EPSS
Vulnrichment
GitHub
Exploit-DB