Skip to content

Commit 2c8106c

Browse files
Merge pull request from GHSA-j5g3-5c8r-7qfx
* failing tests * implement fix + tests passing
1 parent 82a36f4 commit 2c8106c

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

packages/server/src/ApolloServer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ export class ApolloServer<in out TContext extends BaseContext = BaseContext> {
221221

222222
this.logger = config.logger ?? defaultLogger();
223223

224-
const apolloConfig = determineApolloConfig(config.apollo);
224+
const apolloConfig = determineApolloConfig(config.apollo, this.logger);
225225

226226
const isDev = nodeEnv !== 'production';
227227

packages/server/src/__tests__/ApolloServer.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,38 @@ describe('ApolloServer construction', () => {
177177
await server.stop();
178178
});
179179
});
180+
181+
it('throws when an API key is not a valid header value', () => {
182+
expect(() => {
183+
new ApolloServer({
184+
typeDefs,
185+
resolvers,
186+
apollo: {
187+
key: 'bar▒baz▒',
188+
},
189+
});
190+
}).toThrowErrorMatchingInlineSnapshot(
191+
`"The API key provided to Apollo Server contains characters which are invalid as HTTP header values. The following characters found in the key are invalid: ▒, ▒. Valid header values may only contain ASCII visible characters. If you think there is an issue with your key, please contact Apollo support."`,
192+
);
193+
});
194+
195+
it('trims whitespace from incoming API keys and logs a warning', () => {
196+
const logger = mockLogger();
197+
expect(() => {
198+
new ApolloServer({
199+
typeDefs,
200+
resolvers,
201+
apollo: {
202+
key: 'barbaz\n',
203+
},
204+
logger,
205+
});
206+
}).not.toThrow();
207+
expect(logger.warn).toHaveBeenCalledWith(
208+
'The provided API key has unexpected leading or trailing whitespace. ' +
209+
'Apollo Server will trim the key value before use.',
210+
);
211+
});
180212
});
181213

182214
const failToStartPlugin: ApolloServerPlugin<BaseContext> = {

packages/server/src/determineApolloConfig.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { createHash } from '@apollo/utils.createhash';
22
import type { ApolloConfig, ApolloConfigInput } from './externalTypes/index.js';
3+
import type { Logger } from '@apollo/utils.logger';
34

45
// This function combines the `apollo` constructor argument and some environment
56
// variables to come up with a full ApolloConfig.
67
export function determineApolloConfig(
78
input: ApolloConfigInput | undefined,
9+
logger: Logger,
810
): ApolloConfig {
911
const apolloConfig: ApolloConfig = {};
1012

@@ -17,9 +19,21 @@ export function determineApolloConfig(
1719

1820
// Determine key.
1921
if (input?.key) {
20-
apolloConfig.key = input.key;
22+
apolloConfig.key = input.key.trim();
2123
} else if (APOLLO_KEY) {
22-
apolloConfig.key = APOLLO_KEY;
24+
apolloConfig.key = APOLLO_KEY.trim();
25+
}
26+
if ((input?.key ?? APOLLO_KEY) !== apolloConfig.key) {
27+
logger.warn(
28+
'The provided API key has unexpected leading or trailing whitespace. ' +
29+
'Apollo Server will trim the key value before use.',
30+
);
31+
}
32+
33+
// Assert API key is a valid header value, since it's going to be used as one
34+
// throughout.
35+
if (apolloConfig.key) {
36+
assertValidHeaderValue(apolloConfig.key);
2337
}
2438

2539
// Determine key hash.
@@ -65,3 +79,17 @@ export function determineApolloConfig(
6579

6680
return apolloConfig;
6781
}
82+
83+
function assertValidHeaderValue(value: string) {
84+
// Ref: node-fetch@2.x `Headers` validation
85+
// https://github.com/node-fetch/node-fetch/blob/9b9d45881e5ca68757077726b3c0ecf8fdca1f29/src/headers.js#L18
86+
const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/g;
87+
if (invalidHeaderCharRegex.test(value)) {
88+
const invalidChars = value.match(invalidHeaderCharRegex)!;
89+
throw new Error(
90+
`The API key provided to Apollo Server contains characters which are invalid as HTTP header values. The following characters found in the key are invalid: ${invalidChars.join(
91+
', ',
92+
)}. Valid header values may only contain ASCII visible characters. If you think there is an issue with your key, please contact Apollo support.`,
93+
);
94+
}
95+
}

0 commit comments

Comments
 (0)