CVE-2026-82747 Overview
CVE-2026-82747 is an Incorrect Authorization vulnerability [CWE-863] in the ash-project/ash Elixir framework. The flaw resides in Ash.Policy.Authorizer and affects resources configured with an access_type :runtime read policy. When every policy scenario for a record is impossible, the authorizer should forbid the record. Instead, the empty-scenario branch retained the record and returned it as authorized. As a result, records denied by runtime read policies are exposed to any actor, including unauthenticated callers. The issue affects ash from version 3.4.44 before 3.32.2.
Critical Impact
Applications relying on runtime read policies leak records that should be forbidden, breaking the authorization model at the framework level.
Affected Products
- ash-project/ash versions >= 3.4.44
- ash-project/ash versions < 3.32.2
- Elixir applications using Ash resources with access_type :runtime read policies
Discovery Timeline
- 2026-09-01 - CVE-2026-82747 published to NVD
- 2026-09-01 - Last updated in NVD database
Technical Details for CVE-2026-82747
Vulnerability Analysis
Ash is a declarative resource framework for Elixir. Its policy authorizer supports two access types: :filter, which compiles authorization into a query filter, and :runtime, which evaluates checks per-record after data is loaded. Runtime checks are used when a policy depends on record content that cannot be expressed as a database filter.
The defect lives in check_result/1 inside lib/ash/policy/authorizer/authorizer.ex. For each record, the authorizer enumerates policy scenarios and discards those that are impossible for the current record and actor. When the resulting scenario list is empty, no policy can grant access and the record must be forbidden. The vulnerable branch instead prepended the record to the authorized accumulator and preserved the previous any_forbidden? flag, producing a positive authorization decision.
Root Cause
The root cause is an inverted terminal case in the scenario reduction. An empty scenario list was treated as "nothing to deny" rather than "nothing can authorize." The distinction matters because Ash uses a positive-authorization model: absence of a satisfiable scenario means the actor is not authorized, not that the record is safe to return.
Attack Vector
Any actor issuing a read against a resource protected only by a runtime read policy receives records that the policy would otherwise forbid. Exploitation requires no special privileges and no crafted input; a normal read request is sufficient. Impact is limited to confidentiality of records governed by runtime read policies.
|> Enum.reject(&scenario_impossible?(&1, authorizer, record))
|> case do
[] ->
- {[record | data], authorizer, any_forbidden?}
+ {data, authorizer, true}
scenarios ->
case do_check_result(scenarios, authorizer, record) do
Source: ash-project/ash commit 6eddb8a. The patch drops the record from the accumulator and forces any_forbidden? to true when all scenarios are impossible.
Detection Methods for CVE-2026-82747
Indicators of Compromise
- Application logs showing successful reads of records that policy audit trails mark as forbidden for the requesting actor.
- Ash policy breakdown logs (Ash.Policy.Info.log?) reporting empty scenario sets alongside authorized results.
- Unexpected records appearing in API responses from resources that declare access_type :runtime in their read policies.
Detection Strategies
- Enumerate resources whose read policies use access_type :runtime and review recent access logs for those resources.
- Enable Ash policy tracing in a non-production environment and replay production read patterns to identify records that should have been denied.
- Compare authorization decisions against expected results using integration tests that assert forbidden records are excluded from responses.
Monitoring Recommendations
- Ingest Ash policy audit logs into a centralized data lake and alert on read operations returning records whose scenarios collapsed to empty.
- Track the deployed ash dependency version across services and flag any release in the 3.4.44 to 3.32.1 range.
- Correlate anomalous data-volume spikes in API responses tied to resources known to use runtime read policies.
How to Mitigate CVE-2026-82747
Immediate Actions Required
- Upgrade ash to version 3.32.2 or later in every application that depends on it.
- Audit every resource for access_type :runtime read policies and review historical access to those resources for improper disclosure.
- Rotate or invalidate any sensitive data suspected to have been exposed through the affected code path.
Patch Information
The fix is committed in ash-project/ash commit 6eddb8a and released in ash 3.32.2. Additional details are published in the GitHub Security Advisory GHSA-4259-gvr2-4xhq, the Erlang Ecosystem Foundation CNA advisory, and OSV entry EEF-CVE-2026-82747.
Workarounds
- Where feasible, rewrite runtime read policies as filter policies (access_type :filter) so authorization is enforced by the underlying data layer rather than post-load evaluation.
- Add an explicit deny-by-default policy so no read path relies solely on scenario evaluation to forbid records.
- Restrict resource read actions behind additional application-layer authorization until the dependency upgrade is deployed.
# Update the ash dependency in mix.exs and fetch the fixed release
# mix.exs
# defp deps do
# [
# {:ash, "~> 3.32.2"}
# ]
# end
mix deps.update ash
mix deps.get
mix compile --force
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

