GHSA-mp66-8ww2-pcwm - GraphQL Tools: Shared legacy executor routes one subscription's results to a different caller
# Cross-tenant subscription data leak in `@graphql-tools/executor-legacy-ws`: a shared `websocket.onmessage` is replaced on every `subscribe()`, and `DATA` frames are delivered without checking the protocol operation id
## Report metadata
| Field | Value |
| --- | --- |
| Package | `@graphql-tools/executor-legacy-ws` (npm, `pkg:npm/%40graphql-tools/executor-legacy-ws`) |
| Repository | https://github.com/ardatan/graphql-tools |
| Component | `buildWSLegacyExecutor` โ the returned executor's `subscribe(observer)` / `websocket.onmessage` handler |
| Vulnerability class | Cross-tenant data leak (subscription results delivered to the wrong caller) |
| Verified against | Source at `b5d1c36ebb8ed3868260ffee5bbcbb423ad5c1f1` (package version 1.1.33); published npm tarball `1.1.33` with matching source at `d304214db06e8a4ce9cb41138f199e3bc6ed36f2`; the same behaviour also reproduces on the current release `1.1.35` |
| API surface | Public documented API (`buildWSLegacyExecutor`) |
| Affected in default configuration | Yes โ `ensureWebsocket()` reuses an already-`OPEN` socket (`index.ts:35-42`), and the socket has a single mutable `onmessage` property (`index.ts:113`). No single-operation-only restriction is documented, and the return type is the general reusable `DisposableExecutor` (`packages/utils/src/executor.ts:34-57`) |
Affected version range: the range recorded for this finding is `<= 1.1.33`, but that is understated โ the same proof of concept reproduces on `1.1.35`, and a byte diff of the built CJS output between `1.1.33` and `1.1.35` shows only one unrelated change (`rejectUnauthorized`).
## Summary
`buildWSLegacyExecutor` keeps one WebSocket in closure state and installs the message handler by assigning to the socket's single `websocket.onmessage` property inside `subscribe()`. Every new subscription therefore overwrites the previous subscriber's handler, and the handler's `case LEGACY_WS.DATA` branch calls `observer.next(data.payload)` without ever comparing
MEDIUM
Severity & confidence
Source severitymedium
Platform severitymedium
Confidencehigh
Exploitationunknown
CVSS-
Affected
Vendors@graphql-tools
Products@graphql-tools/executor-legacy-ws
Reporting sources (2)
GitHub Security Advisories
NIST NVD - National Vulnerability Database
Timeline & provenance
Published2026-10-28T21:05:07
Last updated2026-10-31T21:01:43
Ingested2026-10-28T21:09:17
FreshnessNEAR-REAL-TIME
Threat typeadvisory
Recommended action
Review the advisory and upgrade affected packages to the first patched version.
Next steps
- Identify affected systems in your environment.
- Apply the vendor patch or mitigation guidance.
- Review logs for indicators described in the advisory.
- Follow the affected vendor/product to track updates.
Confidence explanation
Reported by a government or cert-grade source (CISA, NCSC, NVD, ENISA, MSRC).
Source type: vendor ยท Original: GitHub Security Advisories