Skip to main content

Ash Framework EUVDEUVD-2026-109637

| CVE-2026-96581 HIGH
Authorization Bypass Through User-Controlled Key (CWE-639)
2026-10-26 EEF
7.6
CVSS 4.0 · Vendor: EEF
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Authenticate as a user of one tenant
  2. Delivery
    Enumerate or obtain another tenant's record id
  3. Exploit
    Call upsert create action with that primary key
  4. Execution
    Record returned and upsert fields overwritten
  5. Persist
    Default upsert rewrites tenant attribute
  6. Impact
    Cross-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.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
Patch available 0.3% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – 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

ash 1.22.0 <3.37.2
ash 2333d01ddf37e5909769a513059b27e3183331c5 <c9f0cdb31e7c084def05f3f5be69dd7bb7721754

Affected Packages

euvd ash fix: 3.37.2

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

Vendor (EEF) PRIMARY 7.6 HIGH
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
vuln.today AI 8.1 HIGH

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).

3.1 AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
4.0 AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N

Primary rating from Vendor (EEF).

CVSS VectorVendor: EEF

Attack Vector
Network
Attack Complexity
Low
Attack Requirements
Present
Privileges Required
Low
User Interaction
None
Vulnerable system: Confidentiality
High
Vulnerable system: Integrity
High
Vulnerable system: Availability
None
Subsequent system: Confidentiality
None
Subsequent system: Integrity
None
Subsequent system: Availability
None

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

Why It Matters

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.

Business Impact: High
Compensating Controls

Apply vendor patch.

Threat Intelligence Overview

EPSS Score
0.3%
Top 83% exploitable
Prevalence
Low
Ash is an application framework in the niche Elixir ecosystem
Data Quality
5 sources
Confidence: Medium

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.

SignalValue
Severity HIGH
CISA KEV No
Public POC No
EPSS 0.3%
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision
Scheduled
Exploitation
None
System Exposure· derived
Open
Automatable
No
Human Impact
High
Technical Impact
Total

Priority Score

38
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +38
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

More in Ash

View all
CVE-2026-55736 MEDIUM POC
5.9 Jun 23

Private argument injection in the Ash Elixir framework (versions 3.0.0 through 3.29.2) allows end users to set action ar

CVE-2021-45688 CRITICAL
9.8 Dec 27

An issue was discovered in the ash crate before 0.33.1 for Rust. Rated critical severity (CVSS 9.8), this vulnerability

CVE-2026-94201 HIGH
8.2 Oct 05

Atom table exhaustion in the Ash framework (Elixir) allows an unauthenticated remote attacker to crash a BEAM node by su

CVE-2026-86338 MEDIUM
6.0 Sep 16

An authorization bypass in the Ash framework (Elixir) lets authenticated, lower-privileged actors recover values they ar

CVE-2026-101028 MEDIUM
6.0 Oct 09

Information disclosure in the Ash framework for Elixir (versions 2.6.0 up to but not including 3.34.6) lets an authentic

CVE-2026-114214 MEDIUM
6.0 Oct 25

An incorrect authorization flaw in the Elixir Ash framework (versions 3.24.0 up to but not including 3.37.1) lets an aut

CVE-2026-82738 MEDIUM
5.9 Sep 01

Persistent record-level denial of service in the ash Elixir resource framework (versions 3.6.3-3.32.1) lets any actor wh

CVE-2026-82737 MEDIUM
5.9 Sep 01

Integer overflow in Ash Framework's vector encoding corrupts stored vectors in any Elixir application using Ash versions

CVE-2026-82735 MEDIUM
5.9 Sep 01

CPU exhaustion in Ash Framework's string type constraint handler allows denial of service against Elixir applications th

CVE-2026-69659 MEDIUM
5.9 Aug 09

Memory exhaustion via decompression bomb in Ash Framework's keyset pagination can terminate Erlang nodes running version

CVE-2026-82752 MEDIUM
5.9 Sep 05

Unbounded string storage in Ash Framework versions 0.10.0 through 3.32.x allows unauthenticated attackers to bypass max_

CVE-2026-82742 MEDIUM
5.9 Sep 01

Memory exhaustion in Ash Framework's runtime filter engine allows an attacker controlling filter inputs to crash an Elix

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy