| Package Name | Ecosystem | Vulnerable Versions | First Patched Version |
|---|---|---|---|
| @apollo/composition | npm | < 2.9.5 | 2.9.5 |
| @apollo/composition | npm | >= 2.10.0-alpha.3, < 2.10.4 | 2.10.4 |
| @apollo/composition | npm | >= 2.11.0-preview.1, < 2.11.5 | 2.11.5 |
| @apollo/composition | npm | >= 2.12.0-preview.1, < 2.12.1 | 2.12.1 |
The vulnerability lies in the composition logic of Apollo Federation, which is responsible for creating a unified supergraph schema from multiple subgraph schemas. The core issue was that access control directives (@authenticated, @requiresScopes, @policy) applied to interface types or their fields were not correctly propagated to the object types that implement those interfaces in the final composed schema.
This allowed an attacker to bypass these access controls. While a query against the interface field would be protected, a query using a GraphQL fragment to directly access the same field on the implementing object type would succeed without any access control checks, as the directive was missing from the object type's definition in the supergraph.
The analysis of the patches reveals three key functions that were at the heart of this vulnerability:
Merger.propagateAuthToInterfaces: This function in composition-js/src/merging/merge.ts was intended to propagate these authorization rules. However, its logic was flawed and incomplete. The patch completely removes this function and replaces it with a more sophisticated system for calculating and merging authorization rules (accessControlAdditionalSources), which correctly handles the propagation.
AuthValidator.verifyAuthRequirementsOnSelectionSet: This function is responsible for validating that fields with transitive dependencies (like @requires) have the necessary authorization. The original implementation had complex and incorrect logic for dealing with interfaces, which failed to properly validate the auth requirements across all implementing types.
AuthRequirementsOnElement.isSubset: This helper function was used by the AuthValidator to determine if one set of auth requirements satisfied another. Its implementation of the comparison logic for Disjunctive Normal Form (DNF) was incorrect, checking for clause equality rather than logical implication. This fundamental flaw in the validation logic meant that the validation could pass incorrectly.
In summary, the vulnerability was caused by a failure to correctly propagate authorization directives from interfaces to implementing types during schema composition. The identified functions are the ones that contained this flawed composition and validation logic. The fix involved removing/rewriting this logic to correctly compute and apply the authorization directives in the final supergraph, and also adding stricter validation to prevent such configurations in subgraphs in the first place.
Merger.propagateAuthToInterfacescomposition-js/src/merging/merge.ts
AuthValidator.verifyAuthRequirementsOnSelectionSetcomposition-js/src/merging/merge.ts
AuthRequirementsOnElement.isSubsetcomposition-js/src/merging/merge.ts
Note that this is a breaking change to Apollo Federation, as it no longer allows user-defined access control directives directly on interfaces types and fields. You will need to remove all access control requirements on interface types/fields and manually apply them to each implementing object type/field, where appropriate.
If users are using the Apollo Studio build pipeline with federation version 2.9 or above, then this composition patch version update is automatic and they only need to adjust the access control requirements in your subgraph schemas as mentioned above.
If users are using Apollo Rover for local composition, they will need to update its composition version (after updating Apollo Router, if necessary) to one of the following versions:
Users will then need adjust the access control requirements in your subgraph schemas as mentioned above.
@authenticated, @requiresScopes, or @policy directives) or not specifying access control requirements on interface types/fields are not affected and do not need to take action.Ongoing coverage of React2Shell