CVE-2026-77454 in ash_sql
Summary
by MITRE • 08/30/2026
Incorrect Authorization vulnerability in ash-project ash_sql allows a caller to bypass a scoping or authorization filter expressed as exists/2 over a relationship that declares both a limit (or from_many?) and a parent(...)-referencing filter or sort.
AshSql.Join.related_query/3 skips the caller-supplied exists predicate for such relationships and delegates it to limit_from_many/5. When the relationship's own filter or sort references parent(...), limit_from_many/5 takes a branch that drops both the limit and the predicate, emitting a bare correlated EXISTS with no predicate. The check then matches any record that has any related row. Most severely, when the expression backs a policy (for example authorize_if expr(exists(memberships, user_id == ^actor(:id)))), the actor-scoping condition disappears and the policy passes for any actor with any related row.
This issue affects ash_sql: from 0.4.1 before 0.7.1.
If you want to get best quality of vulnerability data, you may have to visit VulDB.
Analysis
by VulDB Data Team • 08/30/2026
The vulnerability identified in AshSql represents a critical failure in authorization logic within the Elixir-based framework, specifically affecting versions ranging from 0.4.1 up to but not including 0.7.1. This flaw stems from an incorrect implementation of relationship scoping and filtering mechanisms that are designed to enforce access control policies based on relational data structures. The core issue arises when a caller attempts to apply an authorization filter using the exists/2 function over a database relationship that is configured with both a limit constraint, such as from_many?, and a parent-referencing filter or sort operation. In secure systems, these filters are intended to restrict query results to only those records where specific conditions regarding related entities are met, thereby ensuring that access decisions align with the defined security policies.
The technical root cause lies in the behavior of the AshSql.Join.related_query/3 function when processing such complex relationship definitions. Instead of correctly integrating the caller-supplied exists predicate into the generated SQL query, this function erroneously delegates the handling of the predicate to a helper routine named limit_from_many/5. This delegation triggers an unintended code path within limit_from_many/5 that is designed for optimizing limited result sets but fails to account for the presence of parent-referencing filters. Consequently, when this specific branch is executed, it discards both the intended limit and the critical authorization predicate. The resulting SQL output is a bare correlated EXISTS clause without any accompanying WHERE conditions or predicates.
The operational impact of this flaw is severe, as it effectively nullifies the security controls that rely on these relationship checks. A standard correlated EXISTS query with no predicate evaluates to true if there exists at least one row in the related table for the current record. This means that instead of verifying a specific condition, such as whether a user has administrative privileges or belongs to a certain group, the system merely verifies the existence of any associated record. For applications using AshSql to enforce policies through expressions like authorize_if expr(exists(memberships, user_id == ^actor(:id))), this bug causes the policy evaluation to pass for any actor who possesses at least one related membership row, regardless of whether that member matches the intended criteria. This constitutes a complete bypass of authorization filters, allowing unauthorized users to access resources they should be denied.
From a classification perspective, this vulnerability aligns with CWE-285, which describes Improper Authorization, as the system fails to enforce proper restrictions on authenticated users attempting to perform actions or access data. Furthermore, it maps directly to MITRE ATT&CK technique T1078, specifically Valid Accounts and potentially T1098 if exploited for privilege escalation by leveraging existing but incorrectly scoped relationships. The flaw is not a buffer overflow or injection attack in the traditional sense but rather a logical error in query generation that undermines the integrity of access control lists defined within the application logic.
Mitigation strategies must prioritize immediate software updates to address this defect. Organizations running affected versions of ash_sql should upgrade to version 0.7.1 or later, where the handling of parent-referencing filters and limits has been corrected to ensure predicates are not dropped during query construction. In environments where an immediate patch is not feasible, temporary workarounds may involve refactoring authorization policies to avoid using exists/2 over relationships that combine limit constraints with parent-scoped sorts or filters. Developers should also implement rigorous code review processes focusing on the generation of SQL queries from high-level Elixir expressions to detect similar logical oversights in other parts of the application stack. Regular security audits and static analysis tools configured to flag complex query constructions can help identify such vulnerabilities before they are deployed into production environments.