CVE-2026-55736
MediumCVSS 5.9Exploitation Probability (EPSS)
Low risk5th percentile - higher than 5% of all known CVEs
Summary
A vulnerability in the Ash library allows an attacker to set the value of a private action argument intended to be controlled only by trusted server-side code. The filtering of private arguments is incomplete both in the regular changeset path (for binary keys) and in the atomic path (no filtering at all).
Risk Assessment
An attacker can inject a value for a private argument, such as an acting_user_id used for authorization, leading to integrity violation or privilege escalation in the application.
Recommendation
Immediately update the ash library to version 3.29.3 or later, which includes a fix that addresses the incomplete filtering of private arguments.
Other vulnerabilities in ash
See all- CVE-2026-67579High
Deserialization of Untrusted Data vulnerability in ash-project ash allows an unauthenticated attacker to inject a filter expression through a forged keyset pagination cursor, resulting in SQL injection or code execution depending on the data layer. Read actions with keyset pagination decode the client-supplied page[:after] or page[:before] cursor in decode_values/2 in lib/ash/page/keyset.ex using non_executable_binary_to_term/2 with [:safe]. That guard blocks new atoms, funs, and ports, but not a struct built from atoms already interned in a running Ash application, so a decoded %Ash.Query.Call{} expression survives and is spliced into the keyset filter as a comparison value in do_filters/4 and evaluated. Because the cursor bypasses the Ash.Expr macro, the runtime never applies the private?/public? gate that would otherwise reject it. On AshPostgres the injected fragment is inlined into the SQL query; on the ETS and Simple data layers it is evaluated in-process as an arbitrary function call. This issue affects ash: from 1.17.0 before 3.31.3.
- CVE-2026-70395Low
Improper Neutralization of Special Elements in Data Query Logic vulnerability in ash-project ash allows an attacker to forge a relationship to a record they cannot name, and to recover the secret value used to look it up. When manage_relationship is used with on_lookup: :relate on a belongs_to relationship, the client-supplied lookup value is passed to Ash.Query.filter/2 without being cast to the attribute type. A nested map submitted where a scalar is expected is therefore interpreted as a filter predicate rather than a literal, so a lookup for a specific record becomes a query for any record matching a condition. The same path omits Ash.Query.limit(1), leaving Ash.read_one/2 able to distinguish no match from one match from several, which turns comparison predicates into an oracle for the lookup value. Authorization is unaffected; the destination read policy still applies.
- CVE-2026-69659Medium
Uncontrolled resource consumption vulnerability in ash-project ash allows an attacker to exhaust node memory via a crafted keyset pagination cursor. Read actions with keyset pagination deserialize client-supplied page[:after] or page[:before] cursor in decode_values/2 in lib/ash/page/keyset.ex, which base64-decodes the value and passes it to :erlang.binary_to_term/2 without bounding its size. The Erlang external term format supports zlib-compressed payloads, which the decoder inflates transparently, so a cursor of a few kilobytes can allocate tens of megabytes of heap in a single call. Ash itself only ever encodes cursors uncompressed, so the decoder accepts a term shape its encoder never produces. Concurrent requests aggregate these allocations and can terminate the node.
- CVE-2025-48044High
In the ash project, there is an incorrect authorization vulnerability that allows authentication bypass. The issue affects files lib/ash/policy/policy.ex and the function 'Elixir.Ash.Policy.Policy':expression/2 in versions from 3.6.3 up to 3.7.0.
- CVE-2025-48043High
The Ash library versions 0.1.0 through 3.6.2 have an authorization vulnerability that allows authentication bypass. The issue is in the file lib/ash/policy/authorizer/authorizer.ex and the strict_filters/2 function.
- CVE-2025-48042High
The ash library versions 0.1.0 through 3.5.39 have an incorrect authorization vulnerability in bulk operations (create, destroy, update). This vulnerability allows exploiting incorrectly configured access control security levels.
Original NVD description (English source)
Improperly Controlled Modification of Dynamically-Determined Object Attributes vulnerability in ash-project ash allows a user to set the value of a private action argument that is intended to be controlled only by trusted server-side code. Action arguments declared with public?: false are meant to be set internally (for example via Ash.Changeset.set_private_argument/3) and must not be settable from end-user input. When a changeset is built from a parameter map, Ash filters out private arguments, but the filtering is incomplete. In the regular changeset path (for_create, for_update, for_destroy), private arguments are stripped only when the parameter key is an atom. When the key is a binary (string), as is the case for user-supplied parameters, the private argument is kept and the user controls its value. In the atomic path (Ash.Changeset.fully_atomic_changeset/4, also reached through atomic and bulk updates), private arguments are not stripped at all, regardless of whether the key is an atom or a binary. An attacker who can submit parameters to an action that defines a private argument can therefore inject a value for that argument. Depending on how the application uses the argument (for example an acting_user_id driving authorization or record ownership), this can lead to an integrity violation or privilege escalation. This issue affects ash: from 3.0.0 before 3.29.3.

