CVE-2026-96581High· 7.6▾ TwilightAuthorization 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.Ac…
▾ Twilight zone — High severity, or a signal on a lesser flaw
impact 41.8 · likelihood 0 · exploitation 0
Need a working PoC? Pro members can cast a request and our team develops one — it lands right here.
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.
ash >= 1.22.0 < 3.37.2ash-project/ash >= 2333d01ddf37e5909769a513059b27e3183331c5 < c9f0cdb31e7c084def05f3f5be69dd7bb7721754Refer to the linked advisories for vendor-supplied fixes and affected version ranges.
Add upsert_condition expr(<tenant attribute> == ^tenant()) to every create action that upserts on the primary key or on an all_tenants? identity, and do not combine it with return_skipped_upsert?. An upsert into another tenant's record then fails with Ash.Error.Changes.StaleRecord (or is skipped in a bulk create) and leaves that record unchanged. This does not help on the Mnesia data layer, which ignores upsert conditions in affected versions.
Connected by shared product, vendor, weakness, or advisory.
CVE-2026-114214Medium· 6.0Loading a through relationship with a limit of 1 in Ash ignores the through path and returns unrelated destination records
CVE-2026-101028Medium· 6.5Incorrect Authorization vulnerability in ash-project ash allows an actor to infer data in related records they cannot read via Ash.count/2, Ash.exists/2 and Ash.aggregate/3. Ash.Actions.Aggregate.run/4 (lib/ash/actions/aggregate.ex) app…
CVE-2026-94201High· 8.2Ash stores :atom-typed attributes as strings and compares them as strings
CVE-2026-93477Medium· 5.9Improperly Controlled Modification of Dynamically-Determined Object Attributes vulnerability in ash-project ash allows a user to set the value of a private action argument on the bulk destroy and bulk update paths. Action arguments decl…
CVE-2026-86338Medium· 6.0Ash field_policies are documented to protect against filter-based information disclosure: when a field the actor may not see is referenced in a filter, it is replaced with an expression that evaluates to nil, so a filter cannot be used a…
CVE-2026-82752Medium· 5.9Improper Validation of Specified Quantity in Input vulnerability in ash-project ash allows an attacker to store a value of arbitrary size in an attribute whose length constraint should bound it. Ash measures string length with Elixir's …