CVE-2026-80223
HighCVSS 7.1Summary
Incorrect Authorization vulnerability in ash_graphql allows an authenticated subscriber in one tenant to receive another tenant's records over GraphQL subscriptions. The subscription resolver authorizes each notification payload in memory: its fast path calls Ash.can/3 with run_queries?: false, which evaluates the read policy filter against the in-memory record via Ash.Expr.eval/2 and never issues a query. Ash applies multitenancy at query-build and data-layer-prefix time, not inside query.filter, so the evaluated policy carries no tenant condition and a tenant-B notification routed to a tenant-A subscriber is emitted whenever the policy filter is true. The single-notification clause has no tenant guard at all, and the batched clause checks only the head of the notification list, so non-head entries authorize purely in memory. A tenant-scoped read is reached only when filter evaluation fails. This issue affects ash_graphql from 1.4.0 before 1.11.0.
Risk Assessment
An authenticated user can access data from other tenants, potentially leading to confidentiality breaches and data isolation violations between clients.
Recommendation
Upgrade ash_graphql to version 1.11.0 or later, which includes the fix. Review subscription configuration and ensure authorization considers tenant context.
Other vulnerabilities in ash_graphql
See all- CVE-2026-82367Low
Vulnerability in ash_graphql can deliver one subscription's resolved records to a different subscriber's topic. The process handling flaw causes data from one run to be incorrectly used in another, leading to unauthorized data exposure.
- CVE-2026-81643Low
Vulnerability in ash_graphql delivers GraphQL subscription payloads for records a subscriber is not authorized to see. The batching flaw skips authorization checks for some notifications.
- CVE-2026-81636High
Allocation of Resources Without Limits or Throttling vulnerability in ash_graphql allows an unauthenticated client to bypass the configured GraphQL query-complexity limit and force an unbounded database read. The query_complexity/3 function multiplies child complexity by the requested page size only when the argument map contains :limit (offset pagination). Relay connections and keyset pagination use first and last, which never match that clause and fall through to the catch-all that returns child_complexity + 1. A nested relay query such as posts(first: 500) { edges { node { comments(first: 500) { ... } } } } therefore scores as trivially cheap while materializing the full fan-out, passing an Absinthe max_complexity cap that rejects the equivalent limit-based query. The fix adds first and last clauses clamped to the action's page size. This issue affects ash_graphql from 0.16.23 before 1.11.0.
- CVE-2026-81633Medium
Improper Input Validation vulnerability in ash_graphql allows an unauthenticated client to crash a relay node(id: ...) query with an unhandled KeyError. The resolve_node/2 function decodes the client-supplied global ID with decode_relay_id/1, which only base64-decodes the string and splits it on : without validating the type segment. The decoded type is passed straight to Map.fetch!(type_to_domain_and_resource_map, type). Because fetch! raises on a missing key, a relay ID whose type segment is a valid atom that is not a relay-exposed type aborts the resolver before its resolve/2 clauses and their rescue handlers run, so the error never becomes a GraphQL error and may expose a stacktrace. Common resource names are easy to guess. The fix uses Map.fetch/2 and returns an Invalid node id error for unknown types. This issue affects ash_graphql from 0.27.0 before 1.11.0.
- CVE-2026-78693Medium
Vulnerability in ash_graphql allows a remote client to read internal field names that the application configured its error_handler to redact. The error path merging flaw re-injects hidden field names into GraphQL error responses.
Original NVD description (English source)
Incorrect Authorization vulnerability in ash-project ash_graphql allows an authenticated subscriber in one tenant to receive another tenant's records over GraphQL subscriptions. The subscription resolver in AshGraphql.Graphql.Resolver authorizes each notification payload in memory: its fast path calls Ash.can/3 with run_queries?: false, which evaluates the read policy filter against the in-memory record via Ash.Expr.eval/2 and never issues a query. Ash applies multitenancy at query-build and data-layer-prefix time, not inside query.filter, so the evaluated policy carries no tenant condition and a tenant-B notification routed to a tenant-A subscriber is emitted whenever the policy filter is true. The single-notification clause has no tenant guard at all, and the batched clause checks only the head of the notification list, so non-head entries authorize purely in memory. A tenant-scoped read is reached only when filter evaluation fails. This issue affects ash_graphql: from 1.4.0 before 1.11.0.

