Skip to main content
Vulnerability Database/CVE-2026-82725

CVE-2026-82725: Ash Phoenix Auth Bypass Vulnerability

CVE-2026-82725 is an authorization bypass flaw in ash_phoenix that lets attackers filter across non-public relationships using controlled form parameters. This post covers technical details, affected versions, and mitigation steps.

Published:

CVE-2026-82725 Overview

CVE-2026-82725 is an authorization bypass vulnerability in the ash_phoenix library for the Ash Framework in Elixir. The flaw resides in AshPhoenix.FilterForm, which resolved user-supplied relationship paths without enforcing the resource author's public/private designation. Attackers who control filter form parameters can filter across relationships marked non-public, turning result rows into a boolean oracle over private related data. This weakness is categorized as Authorization Bypass Through User-Controlled Key [CWE-639]. The issue affects ash_phoenix versions from 0.6.0-rc.1 before 2.3.25.

Critical Impact

Attackers with access to filter form parameters can infer values of private relationship fields by observing filter results, leaking data the application intentionally hid from public queries.

Affected Products

  • ash_phoenix versions 0.6.0-rc.1 through 2.3.24
  • Applications using AshPhoenix.FilterForm with user-supplied filter parameters
  • Elixir/Phoenix projects built on the Ash Framework that expose FilterForm to untrusted input

Discovery Timeline

  • 2026-08-31 - CVE-2026-82725 published to NVD
  • 2026-09-01 - Last updated in NVD database

Technical Details for CVE-2026-82725

Vulnerability Analysis

AshPhoenix.FilterForm accepts filter parameters directly from user-controlled form input, including a path describing a chain of relationship hops and a terminal field. The library used Ash.Resource.Info.related/2 to resolve each hop in the path. That function traverses relationships regardless of whether the resource author marked them public or private. Only the terminal field was checked for publicity, and even that check was incomplete.

Additionally, parse_path_and_field/2 rewrote a field value that named a relationship into an extra path segment. As a result, a parameter such as field=some_private_rel was silently accepted and folded into the traversal. The resulting reference was passed to Ash.Query.do_filter/2, which does not enforce the public-only restriction that Ash.Filter.parse_input/2 applies. An attacker submits filter expressions that reference private relationships and observes which rows are returned. The presence or absence of records under specific predicates reveals values of hidden fields one bit at a time.

Root Cause

The root cause is inconsistent authorization enforcement between the two Ash query entry points. Ash.Filter.parse_input/2 rejects references to non-public fields and relationships, but Ash.Query.do_filter/2 trusts its caller. AshPhoenix.FilterForm built references from raw form input and handed them to do_filter/2 without applying the same public-only check on every relationship hop.

Attack Vector

Exploitation requires only the ability to submit filter form parameters, which usually means an authenticated low-privilege user of the Phoenix application. The attacker crafts filter predicates that traverse private relationships and infers hidden values from the boolean response of whether records match. No special client, protocol manipulation, or memory corruption primitive is needed.

text
          } = predicate,
          resource
        ) do
+    related_resource = public_related(resource, path)
+
     ref =
-      case Ash.Resource.Info.public_calculation(
-             Ash.Resource.Info.related(resource, path),
-             field
-           ) do
-        nil ->
-          {:ok, Ash.Expr.expr(^Ash.Expr.ref(List.wrap(path), field))}
-
-        %{calculation: {module, calc_opts}} = calc ->
-          with {:ok, input} <-
-                 Ash.Query.validate_calculation_arguments(
-                   calc,
-                   arguments.input || %{}
-                 ),
-               {:ok, calc} <-
-                 Ash.Query.Calculation.new(
-                   calc.name,
-                   module,
-                   calc_opts,
-                   calc.type,
-                   calc.constraints,
-                   arguments: input,
-                   async?: calc.async?,
-                   filterable?: calc.filterable?,
-                   sortable?: calc.sortable?,

Source: GitHub Commit a3691a3. The patch introduces public_related/2, which walks each hop using Ash.Resource.Info.public_relationship/2 and rejects the first non-public hop before a reference is built.

Detect Identity Attacks the Moment Authentication Fails

Singularity™ Identity surfaces credential misuse, lateral movement, and privilege escalation in real time, so you can contain the breach before it spreads.

Stop Identity Attacks

Detection Methods for CVE-2026-82725

Indicators of Compromise

  • Filter form submissions containing path or field parameters that name relationships not declared public? true in the target Ash resource.
  • Repeated filter queries from the same session that differ only in a predicate value, consistent with boolean-oracle probing of a hidden field.
  • Application logs showing Ash.Query.do_filter/2 invocations with references that would have been rejected by Ash.Filter.parse_input/2.

Detection Strategies

  • Audit every LiveView or controller that instantiates AshPhoenix.FilterForm with user-controlled parameters and inventory which resources are exposed.
  • Grep the codebase for relationships lacking public? true and cross-reference them against resources reachable through FilterForm.
  • Add request logging that captures the resolved filter AST so anomalous references to private relationships surface in review.

Monitoring Recommendations

  • Alert on bursts of filter requests from a single user against the same resource within short time windows, which indicate oracle-style enumeration.
  • Track 4xx/5xx rates on Phoenix endpoints backing FilterForm after upgrading, since the patched version now returns errors for previously accepted inputs.
  • Correlate filter parameter values against a denylist of known private relationship names for the deployed resources.

How to Mitigate CVE-2026-82725

Immediate Actions Required

  • Upgrade ash_phoenix to version 2.3.25 or later in mix.exs and run mix deps.update ash_phoenix.
  • Review all Ash resources exposed through AshPhoenix.FilterForm and confirm that any relationship intended to remain confidential is not marked public? true.
  • Redeploy affected Phoenix applications after dependency resolution and run the full test suite to catch newly rejected filter inputs.

Patch Information

The fix is committed in GitHub Commit a3691a3 and documented in GitHub Security Advisory GHSA-7xhg-xphm-f458. Additional coordination details are in the CNA advisory for CVE-2026-82725 and the OSV entry. The patched code resolves each relationship hop with Ash.Resource.Info.public_relationship/2 and requires the terminal field to be public.

Workarounds

  • If immediate upgrade is not possible, wrap FilterForm parameters with an application-level allowlist that validates every path segment and field against known-public schema names.
  • Restrict access to endpoints exposing FilterForm so that only trusted authenticated roles can submit filter parameters until the patch is applied.
  • Temporarily disable filter UI surfaces that expose resources with sensitive private relationships.
bash
# Update ash_phoenix in mix.exs
# {:ash_phoenix, "~> 2.3.25"}
mix deps.update ash_phoenix
mix deps.get
mix compile --force
mix test

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.