Skip to main content

Ash Framework CVE-2026-70395

| EUVDEUVD-2026-54939 LOW
Improper Neutralization of Special Elements in Data Query Logic (CWE-943)
2026-08-09 EEF
2.1
CVSS 4.0 · Vendor: EEF
View

Attack ChainAIDerived

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

  1. Access
    Identify exposed manage_relationship action with on_lookup: :relate
  2. Delivery
    Submit nested map predicate instead of scalar lookup value
  3. Exploit
    Ash.Query.filter/2 interprets map as filter expression
  4. Execution
    Ash.read_one/2 returns distinguishable no-match/one-match/multi-match states
  5. Persist
    Binary-search oracle recovers secret field value
  6. Impact
    Forge belongs_to relationship to otherwise inaccessible record

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization Query language parameterization
Exploitation Conditions

Exploitation requires that the target application uses Ash's manage_relationship feature configured with on_lookup: :relate on a belongs_to association - this is a non-default, application-developer-chosen option and not present in every Ash deployment. The attacker must be able to reach the Ash action that performs this managed relationship (e.g., via an HTTP POST/PUT to a Phoenix API endpoint, a GraphQL mutation, or any other exposed interface that processes a changeset with this configuration). No authentication is required per the CVSS PR:N rating, but the destination resource's read policy still applies, so records the attacker is already unauthorized to read cannot be exfiltrated as data - only their existence and matching field values can be inferred. Exploitation is further limited to belongs_to relationships specifically; has_many and many_to_many paths were already protected by the type-casting logic that this fix mirrors. The missing limit(1) call is the element that elevates a type-confusion flaw to an oracle; without it, the attacker cannot distinguish one-match from multiple-match states.

Impact

The provided CVSS 4.0 score of 2.1 reflects genuinely limited real-world impact: confidentiality and integrity impacts are both Low, availability is None, and there is no subsequent-system scope change. The AT:P (Attack Requirements: Present) correctly captures that this vulnerability requires a non-default application configuration - specifically the use of on_lookup: :relate on a belongs_to managed relationship, which is not the common case. The description explicitly states authorization is unaffected and the destination read policy still applies, meaning an attacker cannot read records they are already unauthorized to view; the oracle only leaks whether a record satisfying a supplied predicate exists and, through iteration, what value a field holds. The CVSS 4.0 vector lists AV:L (Local), which conflicts with the description's framing of 'client-supplied lookup value' - in typical Phoenix/Ash web deployments these values arrive over the network. This is a notable discrepancy: if the attack vector is genuinely local, exposure is very limited; if the application exposes this code path via an HTTP or GraphQL API (the more common deployment model), the real-world attack vector is network. Security teams should verify how their application surfaces manage_relationship actions before accepting the AV:L rating as controlling. No KEV listing and no public exploit code exist, and EPSS data was not provided; the issue appears to be a niche logic flaw rather than a broadly weaponizable vulnerability.

Exploit ScenarioDerived

An attacker interacting with a Phoenix or Plug application that exposes a create or update action using manage_relationship with on_lookup: :relate on a belongs_to field submits a nested map - for example, %{gte: "a"} - instead of a plain identifier string. Because the value is not cast to the attribute's declared type, Ash interprets it as a filter predicate against the destination resource; the three-outcome response from Ash.read_one/2 (no match, one match, multiple matches) then functions as a comparison oracle. By submitting a series of range predicates the attacker performs a binary search, recovering an unknown secret token or ID value without ever needing to guess it directly, and ultimately forges a valid relationship to the target record.

Monitor Track and reassess. Why: LOW severity (CVSS 0.1-3.9).
Patch available 0.1% exploitation probability (EPSS)

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

Alert me

AnalysisAIv1 – Aug 09, 2026

Query injection and oracle enumeration in Ash Framework (ash-project/ash) versions 1.52.0-rc.11 through pre-3.31.1 allow an attacker to forge a belongs_to relationship to a record whose identifier they cannot directly name, and to systematically recover secret lookup values via a comparison oracle. The root cause is a two-part failure in the managed_relationship on_lookup: :relate code path: client-supplied values reach Ash.Query.filter/2 without type-casting, so a nested map is interpreted as a filter predicate rather than a literal scalar, and the missing Ash.Query.limit(1) call lets Ash.read_one/2 distinguish zero, one, and multiple matches - converting boolean filter predicates into an oracle. No public exploit has been identified at time of analysis; a vendor patch is available at version 3.31.1.

RemediationAI

The primary fix is to upgrade ash to version 3.31.1 or later, which introduces type-casting via Ash.Filter.get_filter/2 before lookup values reach Ash.Query.filter/2 and adds Ash.Query.limit(1) to eliminate the oracle signal; the upstream patch commit is 09f42593035bceb0f6153dd7ee45cc49d108300a (https://github.com/ash-project/ash/commit/09f42593035bceb0f6153dd7ee45cc49d108300a). For teams unable to upgrade immediately, the most targeted compensating control is to audit all manage_relationship definitions and remove or replace any on_lookup: :relate usage on belongs_to relationships until patched; replacing with on_lookup: :ignore or requiring application-layer validation of lookup keys before the changeset is submitted eliminates the injection surface. Input validation at the API boundary (rejecting non-scalar values for fields declared as scalar types) provides defence-in-depth but is not a substitute for the patch because the flaw is inside the framework layer. No side-effect concerns have been identified for the upgrade path itself.

Affected VersionsENISA

ash 571c138140e71cea24005189f45d7a63c8d2ed20 <09f42593035bceb0f6153dd7ee45cc49d108300a
ash 1.52.0-rc.11 <3.31.1

Affected Packages

euvd ash fix: 3.31.1

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 (cpe:2.3:a:ash-project:ash:*:*:*:*:*:*:*:*) is an Elixir resource management and API framework. The vulnerability lives in Ash.Actions.ManagedRelationships, the module that handles manage_relationship callbacks. Under CWE-943 (Improper Neutralization of Special Elements in Data Query Logic), the flaw arises because the on_lookup: :relate branch for belongs_to relationships passes the raw client-supplied key map directly to Ash.Query.filter/2 without first routing it through Ash.Filter.get_filter/2, which is responsible for casting each value to its declared attribute type. In Ash's query DSL, a nested map where a scalar is expected is a valid filter expression (e.g., %{gt: 42}), not a literal - so the caller can submit structured predicates rather than plain identifiers. A second defect compounds the first: the same code path omits Ash.Query.limit(1) before calling Ash.read_one/2, whose three observable return states ({:ok, nil}, {:ok, found}, {:error, ...} on ambiguous) function as a binary/ternary oracle. The commit diff confirms both fixes: wrapping key handling in Ash.Filter.get_filter/2 and inserting Ash.Query.limit(1) prior to Ash.read_one/2.

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 2.1 LOW
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N
vuln.today AI 4.8 MEDIUM

Network vector because client-submitted API values trigger the flaw; AC:H because on_lookup: :relate is a non-default developer configuration; C:L and I:L reflect oracle-based secret recovery and relationship forgery with no availability impact.

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

Primary rating from Vendor (EEF).

CVSS VectorVendor: EEF

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

DescriptionCVE.org

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.

This issue affects ash: from 1.52.0-rc.11 before 3.31.1.

Threat Intelligence Overview

EPSS Score
0.1%
Top 96% exploitable
Prevalence
Low
Elixir-specific resource framework, niche language ecosystem
Data Quality
6 sources
Confidence: High

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 LOW
CISA KEV No
Public POC No
EPSS 0.1%
Patch available Yes
Active threat No
Deciding rule
LOW severity (CVSS 0.1-3.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· derived
Defer
Exploitation· derived
None
System Exposure· derived
Small
Automatable· derived
No
Human Impact· derived
Low

Priority Score

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

Attack Technique

Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.

NoSQL injection exploits databases that don't use traditional SQL syntax-like MongoDB, CouchDB, or Redis-by manipulating queries through unsanitized user input.

More in Ash

View all
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-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-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

CVE-2026-82745 MEDIUM
5.9 Sep 01

Silent record overwrite in Ash's ETS and Mnesia data layers allows any actor who can supply a primary key on a create ac

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