You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* CSP fixes
* Update snapshots
* spell check
* add a test that actually validates the whole point of this change :)
* Apply new config option `allowDynamicStyling` for explorer/sandbox
With the updated (more restrictive) CSP, the dynamic styling
implemented by explorer/sandbox now triggers a CSP error. With
this new option, we can disable the dynamic styles (and just apply
them ourselves in our nonced inline styles).
* oops wrong symbol
* test cleanup
* warn on precomputedNonce configuration
The previous implementation of CSP nonces within the landing pages did not take full advantage of the security benefit of using them. Nonces should only be used once per request, whereas Apollo Server was generating one nonce and reusing it for the lifetime of the instance. The reuse of nonces degrades the security benefit of using them but does not pose a security risk on its own. The CSP provides a defense-in-depth measure against a _potential_ XSS, so in the absence of a _known_ XSS vulnerability there is likely no risk to the user.
9
+
10
+
The mentioned fix also coincidentally addresses an issue with using crypto functions on startup within Cloudflare Workers. Crypto functions are now called during requests only, which resolves the error that Cloudflare Workers were facing. A recent change introduced a `precomputedNonce` configuration option to mitigate this issue, but it was an incorrect approach given the nature of CSP nonces. This configuration option is now deprecated and should not be used for any reason since it suffers from the previously mentioned issue of reusing nonces.
11
+
12
+
Additionally, this change adds other applicable CSPs for the scripts, styles, images, manifest, and iframes that the landing pages load.
13
+
14
+
A final consequence of this change is an extension of the `renderLandingPage` plugin hook. This hook can now return an object with an `html` property which returns a `Promise<string>` in addition to a `string` (which was the only option before).
Copy file name to clipboardExpand all lines: docs/source/api/plugin/landing-pages.mdx
-13Lines changed: 0 additions & 13 deletions
Original file line number
Diff line number
Diff line change
@@ -460,19 +460,6 @@ The default value is `false`, in which case the landing page displays a basic `c
460
460
461
461
You can configure the Explorer embedded on your Apollo Server endpoint with display and functional options. For supported options, see [`embed` options](#embed-options).
462
462
463
-
</td>
464
-
</tr>
465
-
<tr>
466
-
<td>
467
-
468
-
###### `precomputedNonce`
469
-
470
-
`string`
471
-
</td>
472
-
<td>
473
-
474
-
The landing page renders with a randomly generated nonce for security purposes. If you'd like to provide your own nonce, you can do so here. This is useful for Cloudflare Workers which can't perform random number generation on startup.
Copy file name to clipboardExpand all lines: docs/source/integrations/plugins-event-reference.mdx
+7-3Lines changed: 7 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -149,7 +149,7 @@ const server = new ApolloServer({
149
149
150
150
</MultiCodeBlock>
151
151
152
-
The handler should return an object with a string `html`field. The value of that field is served as HTML for any requests with `accept: text/html` headers.
152
+
The handler should return an object with a string `html`property. The value of that property is served as HTML for any requests with `accept: text/html` headers. The `html` property can also be an `async` function that returns a string. This function is called for each landing page request.
153
153
154
154
For more landing page options, see [Changing the landing page](../workflow/build-run-queries/#changing-the-landing-page).
155
155
@@ -166,7 +166,11 @@ const server = new ApolloServer({
166
166
async serverWillStart() {
167
167
return {
168
168
async renderLandingPage() {
169
-
return { html: `<html><body>Welcome to your server!</body></html>` };
169
+
return {
170
+
async html() {
171
+
return`<html><body>Welcome to your server!</body></html>`;
172
+
},
173
+
};
170
174
},
171
175
};
172
176
},
@@ -354,7 +358,7 @@ This event is _not_ associated with your GraphQL server's _resolvers_. When this
354
358
355
359
> If the operation is anonymous (i.e., the operation is `query { ... }` instead of `query NamedQuery { ... }`), then `operationName` is `null`.
356
360
357
-
If a `didResolveOperation` hook throws a [`GraphQLError`](../data/errors#custom-errors), that error is serialized and returned to the client with an HTTP status code of 500 unless [it specifies a different status code](../data/errors#setting-http-status-code-and-headers).
361
+
If a `didResolveOperation` hook throws a [`GraphQLError`](../data/errors#custom-errors), that error is serialized and returned to the client with an HTTP status code of 500 unless [it specifies a different status code](../data/errors#setting-http-status-code-and-headers).
358
362
359
363
The `didResolveOperation` hook is a great spot to perform extra validation because it has access to the parsed and validated operation and the request-specific context (i.e., `contextValue`). Multiple plugins can run the `didResolveOperation` in parallel, but if more than one plugin throws, the client only receives a single error.
var embeddedExplorerConfig = {"graphRef":"graph@current","target":"#embeddableExplorer","initialState":{"document":"query Test { id }","headers":{"authorization":"true"},"variables":{"option":{"a":"val","b":1,"c":true}},"displayOptions":{"showHeadersAndEnvVars":true,"docsPanelState":"open","theme":"light"}},"persistExplorerState":true,"includeCookies":true,"runtime":"@apollo/[email protected]","runTelemetry":true};
66
+
var embeddedExplorerConfig = {"graphRef":"graph@current","target":"#embeddableExplorer","initialState":{"document":"query Test { id }","headers":{"authorization":"true"},"variables":{"option":{"a":"val","b":1,"c":true}},"displayOptions":{"showHeadersAndEnvVars":true,"docsPanelState":"open","theme":"light"}},"persistExplorerState":true,"includeCookies":true,"runtime":"@apollo/[email protected]","runTelemetry":true,"allowDynamicStyles":false};
var embeddedExplorerConfig = {"graphRef":"graph@current","target":"#embeddableExplorer","initialState":{"headers":{"authorization":"true"},"displayOptions":{}},"persistExplorerState":false,"includeCookies":true,"runtime":"@apollo/[email protected]","runTelemetry":true};
116
+
var embeddedExplorerConfig = {"graphRef":"graph@current","target":"#embeddableExplorer","initialState":{"headers":{"authorization":"true"},"displayOptions":{}},"persistExplorerState":false,"includeCookies":true,"runtime":"@apollo/[email protected]","runTelemetry":true,"allowDynamicStyles":false};
var embeddedExplorerConfig = {"graphRef":"graph@current","target":"#embeddableExplorer","initialState":{"collectionId":"12345","operationId":"abcdef","displayOptions":{}},"persistExplorerState":false,"includeCookies":true,"runtime":"@apollo/[email protected]","runTelemetry":true};
167
+
var embeddedExplorerConfig = {"graphRef":"graph@current","target":"#embeddableExplorer","initialState":{"collectionId":"12345","operationId":"abcdef","displayOptions":{}},"persistExplorerState":false,"includeCookies":true,"runtime":"@apollo/[email protected]","runTelemetry":true,"allowDynamicStyles":false};
var embeddedExplorerConfig = {"graphRef":"graph@current","target":"#embeddableExplorer","initialState":{"displayOptions":{}},"persistExplorerState":false,"includeCookies":false,"runtime":"@apollo/[email protected]","runTelemetry":true};
216
+
var embeddedExplorerConfig = {"graphRef":"graph@current","target":"#embeddableExplorer","initialState":{"displayOptions":{}},"persistExplorerState":false,"includeCookies":false,"runtime":"@apollo/[email protected]","runTelemetry":true,"allowDynamicStyles":false};
var embeddedExplorerConfig = {"graphRef":"graph@current","target":"#embeddableExplorer","initialState":{"headers":{"authorization":"true"},"displayOptions":{}},"persistExplorerState":false,"includeCookies":true,"runtime":"@apollo/[email protected]","runTelemetry":false};
268
+
var embeddedExplorerConfig = {"graphRef":"graph@current","target":"#embeddableExplorer","initialState":{"headers":{"authorization":"true"},"displayOptions":{}},"persistExplorerState":false,"includeCookies":true,"runtime":"@apollo/[email protected]","runTelemetry":false,"allowDynamicStyles":false};
0 commit comments