From 8d1179ed007b90c56382826499011af0dde16439 Mon Sep 17 00:00:00 2001 From: David Glasser Date: Tue, 8 Jun 2021 13:54:26 -0700 Subject: [PATCH] Avoid ws CVE-2021-32640 (#5285) Apollo Server 2 depends on `subscriptions-transport-ws` for a superficial implementation of GraphQL subscription support. (Apollo Server 3.0.0 will not have built-in subscription support.) This unmaintained package depended on `ws` v5. All releases of v5 `ws` have a server DOS vulnerability: https://www.npmjs.com/advisories/1748 This change: - Removes the direct dependency on `ws` from `apollo-server-core`. This dependency was only used for types, so its imports have been changed to `import type` which pulls from `@types/ws`. - Updates the `subscriptions-transport-ws` dependency in `apollo-server-core` and `apollo-server-express` to the newly-released 0.9.19, which allows for `ws` v6 and v7. This means that via appropriate `npm` installations, you can install one of the non-vulnerable versions (6.2.2+ or 7.4.6+). Note that there are backwards incompatible changes in ws v6 and v7; see https://github.com/websockets/ws/releases/tag/6.0.0 and https://github.com/websockets/ws/releases/tag/7.0.0 for details. - Does some other small upgrades of ws-related packages. Note that the best way to protect yourself from this vulnerability is to avoid using the unmaintained `subscriptions-transport-ws` entirely by passing `subscriptions: false` to `new ApolloServer` and (if you do need to use subscriptions) using a maintained GraphQL subscription server such as `graphql-ws`. --- package-lock.json | 31 ++++++------------- package.json | 4 +-- packages/apollo-server-core/package.json | 5 ++- .../apollo-server-core/src/ApolloServer.ts | 4 +-- packages/apollo-server-core/src/types.ts | 4 +-- packages/apollo-server-express/package.json | 2 +- .../apollo-server-express/src/ApolloServer.ts | 2 +- 7 files changed, 19 insertions(+), 33 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7e0f7824f37..ef67a29e4bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7987,9 +7987,9 @@ } }, "@types/ws": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.2.tgz", - "integrity": "sha512-PbeN0Eydl7LQl4OIav29YmkO2LxbVuz3nZD/kb19lOS+wLgIkRbWMNmU/QQR7ABpOJ7D7xDOU8co7iohObewrw==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.4.tgz", + "integrity": "sha512-d/7W23JAXPodQNbOZNXvl2K+bqAQrCMwlh/nuQsPSQk6Fq0opHoPrUw43aHsvSbIiQPr8Of2hkFbnz1XBFVyZQ==", "requires": { "@types/node": "*" } @@ -8484,9 +8484,8 @@ "loglevel": "^1.6.7", "lru-cache": "^6.0.0", "sha.js": "^2.4.11", - "subscriptions-transport-ws": "^0.9.11", - "uuid": "^8.0.0", - "ws": "^6.0.0" + "subscriptions-transport-ws": "^0.9.19", + "uuid": "^8.0.0" }, "dependencies": { "@apollographql/graphql-playground-html": { @@ -8568,7 +8567,7 @@ "graphql-subscriptions": "^1.0.0", "graphql-tools": "^4.0.8", "parseurl": "^1.3.2", - "subscriptions-transport-ws": "^0.9.16", + "subscriptions-transport-ws": "^0.9.19", "type-is": "^1.6.16" }, "dependencies": { @@ -23802,25 +23801,15 @@ "dev": true }, "subscriptions-transport-ws": { - "version": "0.9.18", - "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.18.tgz", - "integrity": "sha512-tztzcBTNoEbuErsVQpTN2xUNN/efAZXyCyL5m3x4t6SKrEiTL2N8SaKWBFWM4u56pL79ULif3zjyeq+oV+nOaA==", + "version": "0.9.19", + "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.19.tgz", + "integrity": "sha512-dxdemxFFB0ppCLg10FTtRqH/31FNRL1y1BQv8209MK5I4CwALb7iihQg+7p65lFcIl8MHatINWBLOqpgU4Kyyw==", "requires": { "backo2": "^1.0.2", "eventemitter3": "^3.1.0", "iterall": "^1.2.1", "symbol-observable": "^1.0.4", - "ws": "^5.2.0" - }, - "dependencies": { - "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "requires": { - "async-limiter": "~1.0.0" - } - } + "ws": "^5.2.0 || ^6.0.0 || ^7.0.0" } }, "superagent": { diff --git a/package.json b/package.json index 64eccc48176..6cce47a2fd7 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,7 @@ "@types/test-listen": "1.1.0", "@types/type-is": "1.6.3", "@types/uuid": "8.3.0", - "@types/ws": "7.4.2", + "@types/ws": "7.4.4", "apollo-fetch": "0.7.0", "apollo-link": "1.2.14", "apollo-link-http": "1.5.17", @@ -128,7 +128,7 @@ "qs-middleware": "1.0.3", "request": "2.88.2", "request-promise": "4.2.6", - "subscriptions-transport-ws": "0.9.18", + "subscriptions-transport-ws": "0.9.19", "supertest": "6.1.3", "test-listen": "1.1.0", "ts-jest": "26.5.6", diff --git a/packages/apollo-server-core/package.json b/packages/apollo-server-core/package.json index 9fd83154bc2..b02277dc91f 100644 --- a/packages/apollo-server-core/package.json +++ b/packages/apollo-server-core/package.json @@ -48,9 +48,8 @@ "loglevel": "^1.6.7", "lru-cache": "^6.0.0", "sha.js": "^2.4.11", - "subscriptions-transport-ws": "^0.9.11", - "uuid": "^8.0.0", - "ws": "^6.0.0" + "subscriptions-transport-ws": "^0.9.19", + "uuid": "^8.0.0" }, "peerDependencies": { "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" diff --git a/packages/apollo-server-core/src/ApolloServer.ts b/packages/apollo-server-core/src/ApolloServer.ts index 77fd03b4e1d..055c4b7fb44 100644 --- a/packages/apollo-server-core/src/ApolloServer.ts +++ b/packages/apollo-server-core/src/ApolloServer.ts @@ -34,12 +34,12 @@ import { } from 'apollo-server-plugin-base'; import runtimeSupportsUploads from './utils/runtimeSupportsUploads'; -import { +import type { SubscriptionServer, ExecutionParams, } from 'subscriptions-transport-ws'; -import WebSocket from 'ws'; +import type WebSocket from 'ws'; import { formatApolloErrors } from 'apollo-server-errors'; import { GraphQLServerOptions, PersistedQueryOptions } from './graphqlOptions'; diff --git a/packages/apollo-server-core/src/types.ts b/packages/apollo-server-core/src/types.ts index bd1bddd9803..04a497b3ed0 100644 --- a/packages/apollo-server-core/src/types.ts +++ b/packages/apollo-server-core/src/types.ts @@ -14,9 +14,7 @@ import { ApolloConfigInput, } from 'apollo-server-types'; import { ConnectionContext } from 'subscriptions-transport-ws'; -// The types for `ws` use `export = WebSocket`, so we'll use the -// matching `import =` to bring in its sole export. -import WebSocket = require('ws'); +import type WebSocket from 'ws'; import { GraphQLExtension } from 'graphql-extensions'; export { GraphQLExtension } from 'graphql-extensions'; diff --git a/packages/apollo-server-express/package.json b/packages/apollo-server-express/package.json index ee30033da9d..50266fe1f3f 100644 --- a/packages/apollo-server-express/package.json +++ b/packages/apollo-server-express/package.json @@ -42,7 +42,7 @@ "graphql-subscriptions": "^1.0.0", "graphql-tools": "^4.0.8", "parseurl": "^1.3.2", - "subscriptions-transport-ws": "^0.9.16", + "subscriptions-transport-ws": "^0.9.19", "type-is": "^1.6.16" }, "devDependencies": { diff --git a/packages/apollo-server-express/src/ApolloServer.ts b/packages/apollo-server-express/src/ApolloServer.ts index c8b3f19ef32..c8f205da7b3 100644 --- a/packages/apollo-server-express/src/ApolloServer.ts +++ b/packages/apollo-server-express/src/ApolloServer.ts @@ -15,7 +15,7 @@ import { Context, Config, } from 'apollo-server-core'; -import { ExecutionParams } from 'subscriptions-transport-ws'; +import type { ExecutionParams } from 'subscriptions-transport-ws'; import accepts from 'accepts'; import typeis from 'type-is'; import { graphqlExpress } from './expressApollo';