CVE-2026-118666 in graphql-tools
Summary
by MITRE • 10/28/2026
GraphQL Tools provides utilities for building, stitching, and mocking GraphQL schemas. Prior to version 1.1.36 of the GraphQL Tools legacy WebSocket executor package, buildWSLegacyExecutor in packages/executors/legacy-ws/src/index.ts reuses one WebSocket and replaces its single websocket.onmessage handler whenever a new overlapping subscription starts. The handler delivers LEGACY_WS.DATA frames to the newest observer without comparing data.id with the subscription operation id, so a caller using the same executor can receive another user's authorized subscription payload while the earlier caller's stream is starved. This issue is fixed in version 1.1.36 of the GraphQL Tools legacy WebSocket executor package.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.
Analysis
by VulDB Data Team • 10/28/2026
The vulnerability identified within the GraphQL Tools library, specifically affecting versions prior to 1.1.36 in its legacy WebSocket executor module, represents a critical flaw in how concurrent subscription requests are managed over persistent connections. GraphQL is widely adopted for building APIs that allow clients to request precise data structures, and subscriptions provide real-time updates via WebSockets. The core issue resides in the buildWSLegacyExecutor function located within packages/executors/legacy-ws/src/index.ts. This component is responsible for establishing and maintaining WebSocket connections used by subscribers to receive live data streams from a GraphQL server. In environments where multiple clients or internal processes utilize the same executor instance, the library attempts to optimize resource usage by reusing a single underlying WebSocket connection rather than creating separate connections for each subscription request.
The technical flaw stems from an incorrect implementation of message routing and handler management within this shared connection model. When a new overlapping subscription is initiated, the code replaces the existing websocket.onmessage event handler with a new one tailored for the incoming request. Crucially, the updated handler does not validate whether the data.id field contained in the incoming LEGACY_WS.DATA frame matches the specific operation id of the current subscriber. Instead, it blindly delivers all received data frames to the newest observer registered with that executor instance. This design oversight means that any message arriving on the shared WebSocket connection is dispatched solely based on temporal recency rather than logical association with a specific subscription context. Consequently, the system fails to isolate traffic between different concurrent subscribers sharing the same transport layer.
The operational impact of this vulnerability is severe, primarily manifesting as an unauthorized data disclosure and denial of service condition for legitimate users. Because the handler delivers payloads without verifying ownership via operation identifiers, a caller using the shared executor can inadvertently receive subscription results intended for another user who holds different authorization privileges or simply has a separate active subscription on the same connection. This leads to information leakage where sensitive GraphQL query results are exposed to unauthorized parties. Simultaneously, the earlier caller experiences starvation of their data stream because incoming messages meant for them are intercepted and delivered to the newer subscriber instead. This breaks the fundamental contract of isolation in multi-tenant applications or even single-user sessions with multiple concurrent subscriptions, potentially leading to significant privacy violations and service degradation.
From a classification perspective, this vulnerability aligns closely with CWE-200: Information Exposure, as it involves the accidental disclosure of information to unauthorized actors due to improper access control mechanisms within the application logic. Furthermore, in the context of attack patterns, this behavior can be associated with ATT&CK technique T1537: Communication Through Distributed Component of Software, although more accurately it reflects a failure in logical isolation akin to CWE-862: Missing Authorization. The flaw exploits the assumption that message handlers are stateless and correctly scoped, ignoring the necessity for explicit correlation between incoming data frames and their originating subscription contexts through unique identifiers.
To mitigate this vulnerability, organizations must immediately upgrade the GraphQL Tools library to version 1.1.36 or later, where the buildWSLegacyExecutor function has been patched to properly validate message origins. The fix ensures that incoming LEGACY_WS.DATA frames are checked against the specific operation id of each active subscription before delivery, thereby restoring proper isolation between concurrent users and preventing cross-subscription data leakage. For systems unable to upgrade immediately due to dependency constraints, implementing a reverse proxy or gateway layer that manages WebSocket connections individually per user session can provide an effective workaround by ensuring that no two distinct logical subscriptions share the same underlying physical connection without explicit routing logic at the network edge.