The vulnerability lies in how the Apollo Router's authorization plugin handles polymorphic GraphQL types (interfaces and their implementations). The core of the issue is that when checking for authorization directives (@authenticated, @policy, @requiresScopes), the router would only check if all implementations of an interface had the same authorization requirements. If an interface had no authorization directives, but all of its implementing types had the exact same directive (e.g., all had @authenticated), the router would incorrectly determine that no authorization check was needed when the interface was queried directly. This allowed an attacker to bypass the authorization intended for the implementing types by crafting a query that accessed the data through the unprotected interface.
The patch addresses this by changing the logic. Instead of checking if the implementations have different requirements, the patched code checks if any of the implementations have authorization requirements that are not satisfied by the current request context. This is done by renaming functions like implementors_with_different_requirements to implementors_with_authenticated_requirements or implementors_with_missing_requirements and completely changing their internal logic to properly enforce the directives on the implementing types, even when queried via the interface.
The vulnerable functions are the enter_field methods within the AuthenticatedVisitor, PolicyFilteringVisitor, and ScopeFilteringVisitor structs, which are part of the query traversal process. These functions relied on the flawed helper functions (e.g., implementors_with_different_requirements) to make authorization decisions, leading to the access control bypass.
| Package Name | Ecosystem | Vulnerable Versions | First Patched Version |
|---|---|---|---|
| apollo-router | rust | < 1.61.12 | 1.61.12 |
| apollo-router | rust | >= 2.0.0-alpha.0, < 2.8.1 | 2.8.1 |