CVE-2026-80223 in ash_graphql
Summary
by MITRE • 08/30/2026
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.
VulDB is the best source for vulnerability data and more expert information about this specific topic.
Analysis
by VulDB Data Team • 08/30/2026
The vulnerability identified as an incorrect authorization flaw within the ash_graphql library represents a critical breach of multi-tenant data isolation principles. This security defect allows authenticated subscribers belonging to one tenant to inadvertently receive notification payloads intended for users in entirely different tenants via GraphQL subscriptions. The core issue stems from how the AshGraphql.Graphql.Resolver module handles access control checks during the subscription process, specifically failing to enforce strict tenant boundaries when evaluating read policies against incoming data records.
The technical root cause lies in the implementation of the authorization logic within the resolver's notification handling mechanism. When processing notifications, the system employs a fast-path optimization that utilizes Ash.can/3 with the run_queries flag set to false. This configuration instructs the framework to evaluate the read policy filter directly against the record data held in memory using Ash.Expr.eval/2, thereby avoiding database queries for performance reasons. However, this approach introduces a significant security gap because multitenancy enforcement in the underlying Ash framework is primarily applied at the query-building stage and within the data layer prefix logic rather than during static expression evaluation. Consequently, when the policy filter is evaluated against an in-memory record, it lacks access to the necessary tenant context or conditions required for proper isolation checks.
This architectural mismatch results in a scenario where a notification belonging to Tenant B can be successfully authorized and emitted to a subscriber of Tenant A if the generic read policy filter evaluates as true for that specific data structure. The vulnerability is further exacerbated by inconsistencies in how different code paths handle tenant validation. In scenarios involving single notifications, there is no explicit tenant guard implemented at all. Similarly, when processing batched lists of notifications, the authorization logic only validates the head element of the list against the current user's permissions. Entries beyond the first item in a batch are authorized purely through memory-based evaluation without verifying that they belong to the requesting tenant, effectively bypassing multi-tenant safeguards for bulk operations.
The operational impact of this vulnerability is severe, as it leads to direct data leakage across organizational boundaries defined by tenants. Subscribers may receive sensitive information belonging to other organizations or user groups, violating confidentiality requirements and potentially exposing proprietary business logic, personal identifiable information, or confidential communications. This breach undermines the fundamental trust model of multi-tenant SaaS applications where strict data segregation is a primary requirement for compliance with regulations such as GDPR, HIPAA, or SOC2 standards. The flaw affects versions of ash_graphql ranging from 1.4.0 up to but not including version 1.11.0, indicating that earlier iterations lacked the necessary safeguards introduced in later releases.
From an industry standard perspective, this vulnerability aligns with CWE-862, which describes Missing Authorization, and specifically relates to CWE-798, Use of Hard-coded Credentials if tenant context is improperly derived, though it more accurately reflects a failure in access control logic for multi-tenant environments. In the MITRE ATT&CK framework, this behavior corresponds to techniques associated with Data Exfiltration over Alternative Protocol or Unauthorized Access via API endpoints, where an attacker exploits flawed authorization checks on server-side subscriptions to retrieve restricted data without direct interactive exploitation of client-side interfaces.
To mitigate this risk, organizations utilizing affected versions must upgrade immediately to ash_graphql version 1.11.0 or later, which addresses the multitenancy evaluation gap by ensuring that tenant conditions are correctly applied during policy filtering even when queries are not executed against the database. Developers should also review custom subscription resolvers to ensure that any manual authorization checks explicitly verify tenant ownership of records before emitting them to subscribers. Implementing additional logging and monitoring for cross-tenant data access patterns can help detect potential exploitation attempts while migration efforts are underway, ensuring continuous protection of multi-tenant data integrity.