Open tconroy opened 4 years ago
@tconroy I could get rid of a view errors with passing these options:
const playground: PlaygroundConfig = {
cdnUrl: 'https://cdn.jsdelivr.net/npm',
faviconUrl: '',
};
The two errors related to index.css
and middleware.js
still remain.
//...
"apollo-server-core": "^2.18.1",
"apollo-server-express": "^2.18.1",
"express": "^4.17.1",
"graphql": "^15.3.0",
"graphql-tools": "^6.2.3",
I had the same problem and solved it. This is a problem with setting the "Content-Security-Policy" header value that the web server responds. need to delete or modify the setting.
In my case, the helmet module was responding, and I solved it by modifying it as follows.
app.use(helmet({ contentSecurityPolicy: (process.env.NODE_ENV === 'production') ? undefined : false }));
Ah, brilliant! That was the same case as me @CatsMiaow -- was using a boilerplate and wasn't aware of the Helmet config. The value you set works perfectly. Thank you for the help!
Where does the helmet config live? I've had a similar issue open for over a year (#1069) and I have no idea where to make this modification. I have no idea what helmet even is; the playground in my case is bundled with ... I'm not even sure, to be honest. Presumably one of these:
"@apollo/gateway": "^0.6.13",
"apollo-datasource-rest": "^0.5.0",
"apollo-server": "^2.9.5",
"apollo-server-testing": "^2.8.0",
I had the same problem and solved it. This is a problem with setting the "Content-Security-Policy" header value that the web server responds. need to delete or modify the setting.
In my case, the helmet module was responding, and I solved it by modifying it as follows.
app.use(helmet({ contentSecurityPolicy: (process.env.NODE_ENV === 'production') ? undefined : false }));
Is there any issue in setting contentSecurityPolicy
to undefined
in production?
https://github.com/helmetjs/helmet/blob/d491d281eb1cc55380046532d24fbc314af836e0/index.ts#L69-L75 undefined is the default. When undefined, it is enabled as the default option.
Disabling contentSecurityPolicy for development is not the best idea, since developers will not notice something does not work until it's in the production.
I think the graphql playground should have all the scripts as npm development dependencies and not hosted on cdn.jsdelivr.net.
Another solution is whitelisting cdn.jsdelivr.net in CSP, but it is not a good idea, since anyone can upload anything on jsdelivr.net, which makes the CSP useless.
This should be reopened. The root of issue lays in insecure playground implementation - this should be addressed based on issues reported by CSP checks. Like get rid of all inline scripts/styles/fonts/images and use whitelisted domain only or locally served files. Then it should be simple to configure helmet without using insecure directives/options.
Like get rid of all inline scripts/styles/fonts/images and use whitelisted domain only or locally served files.
I'm only tangentially familiar with this particular issue, but why not use inline styles and other assets for the gql playground? This would also make it functional when offline, and as far as I'm aware, the playground is typically used for development, not for users in production.
Well you don't want to disable CSP headers for development envs, because you will miss other issues with it, up until production, on your API. Therefore your playground is not working anyway or you introduce security issue with header policies to the whole app or you waste some resources and create a separate app with different header policy just for playground. The issue is even more serious if you plan to use playground as public and open API tool.
The other approach for this might be generating proper exclusions for CSP headers, I think.
And what about the opposite? @zsolt-dev
const appConfig = app.get(AppConfigService);
app.use(helmet({ contentSecurityPolicy: (appConfig.environment === 'localhost') ? false : undefined }));
That way we have enabled CSP in other environments but localhost...
PD: yes this only works if you don't want to publish the playground...
For those of you running into this after upgrading helmet
to v5
or higher (as I did), you will also get a console error and blocked response because of COEP/CORP headers (in Chrome, but not in Firefox). This happens because the initial request to cdn.jsdelivr.com
yields a 307 Temporary Redirect from http
to https
(because of the HSTS configuration on the jsdelivr side). This redirect itself does not contain the proper CORP headers -- I think.
I have addressed this at jsdelivr's repo: https://github.com/jsdelivr/jsdelivr/issues/18201#issuecomment-1012912236
To circumvent this, also disable the crossOriginEmbedderPolicy
header:
app.use(helmet({ contentSecurityPolicy: false, crossOriginEmbedderPolicy: false }))
@kweij you're the hero of the day, thanks for taking the time to add this precise comment, thanks!!!
@bke-daniel Your suggestion solved my issue. Thanks!
I have filed a bug at Chrome for this (the COEP / CORP headers) issue, as it seems that this is not the way the browser should handle this (i.e.: HSTS redirects should be internal to the browser and not expect CORP headers):
https://bugs.chromium.org/p/chromium/issues/detail?id=1287500
EDIT: A fix has been made Jan 19, 2022 👍
I'm facing this currently, localhost:4000/graphql was working fine an hour back and now it's gone down. First the request took a long time to fetch and then when I reinstalled all of my modules, the apollo server doesn't even run
If you want to still have CSP headers but limit it somewhat (instead of disabling entirely)
const devContentSecurityPolicy = {
directives: {
scriptSrc: ["'self'", "'unsafe-inline'", 'https://cdn.jsdelivr.net'],
imgSrc: ["'self'", 'data:', 'https://cdn.jsdelivr.net'],
},
};
app.use(
helmet({
// when undefined it will load the default option: https://github.com/graphql/graphql-playground/issues/1283#issuecomment-723705276
contentSecurityPolicy: IS_DEV ? devContentSecurityPolicy : undefined,
}),
);
I had the same problem and solved it. This is a problem with setting the "Content-Security-Policy" header value that the web server responds. need to delete or modify the setting.
In my case, the helmet module was responding, and I solved it by modifying it as follows.
app.use(helmet({ contentSecurityPolicy: (process.env.NODE_ENV === 'production') ? undefined : false }));
Thanks you so much, I was trying to setup the graphql playground but it stayed at the loading..., until I google for a some minutes I came across of this post. thanks
Correct me if I'm wrong but this issue is still ongoing as there is no current fix for production Open APIs serving this playground.
Adding headers
to ApolloServerPluginLandingPageLocalDefault
options worked for me.
Versions:
"@apollo/server": "^4.0.3",
"@apollo/server-plugin-landing-page-graphql-playground": "^4.0.0",
ApolloServerPluginLandingPageLocalDefault({
headers: {
"Content-Security-Policy": "default-src 'self' https://apollo-server-landing-page.cdn.apollographql.com;",
},
}),
Adding
headers
toApolloServerPluginLandingPageLocalDefault
options worked for me. Versions:"@apollo/server": "^4.0.3", "@apollo/server-plugin-landing-page-graphql-playground": "^4.0.0",
ApolloServerPluginLandingPageLocalDefault({ headers: { "Content-Security-Policy": "default-src 'self' https://apollo-server-landing-page.cdn.apollographql.com;", }, }),
Unfortunately, this does not work for me. Maybe I need to define different settings?
Refused to load the image 'https://apollo-server-landing-page.cdn.apollographql.com/_latest/assets/favicon.png' because it violates the following Content Security Policy directive: "img-src 'self' data:".
graphql:22 Refused to load the image 'https://apollo-server-landing-page.cdn.apollographql.com/_latest/assets/favicon.png' because it violates the following Content Security Policy directive: "img-src 'self' data:".
graphql:1 Refused to load the script 'https://embeddable-sandbox.cdn.apollographql.com/_latest/embeddable-sandbox.umd.production.min.js?runtime=%40apollo%2Fserver%404.7.4' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
graphql:71 Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-OK7pAH5PWuMz0B3Z+8KJD+AVvhgLxb2X4W00TmJw2M8='), or a nonce ('nonce-...') is required to enable inline execution.
Refused to load the image 'https://apollo-server-landing-page.cdn.apollographql.com/_latest/assets/favicon.png' because it violates the following Content Security Policy directive: "img-src 'self' data:".
graphql:1 Refused to load manifest from 'https://apollo-server-landing-page.cdn.apollographql.com/_latest/manifest.json' because it violates the following Content Security Policy directive: "default-src 'self' Note that 'manifest-src' was not explicitly set, so 'default-src' is used as a fallback.
Any hint is appreciated!
@krisgardiner Are you still using the same setup? I saw "@apollo/server-plugin-landing-page-graphql-playground" is now deprecated.
My setup is now as in https://docs.nestjs.com/graphql/quick-start#apollo-sandbox, but it does not work.
The HTML source looks as follows:
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-b5693f538f65c3b4938853dfcf85ff99c16ab6ef4dc5341e87b0c69ccbafa012' https://apollo-server-landing-page.cdn.apollographql.com https://embeddable-sandbox.cdn.apollographql.com https://embeddable-explorer.cdn.apollographql.com; style-src 'nonce-b5693f538f65c3b4938853dfcf85ff99c16ab6ef4dc5341e87b0c69ccbafa012' https://apollo-server-landing-page.cdn.apollographql.com https://embeddable-sandbox.cdn.apollographql.com https://embeddable-explorer.cdn.apollographql.com https://fonts.googleapis.com; img-src https://apollo-server-landing-page.cdn.apollographql.com; manifest-src https://apollo-server-landing-page.cdn.apollographql.com; frame-src https://explorer.embed.apollographql.com https://sandbox.embed.apollographql.com https://embed.apollo.local:3000" />
...
<script nonce="b5693f538f65c3b4938853dfcf85ff99c16ab6ef4dc5341e87b0c69ccbafa012">
var initialEndpoint = window.location.href;
var embeddedSandboxConfig = {"target":"#embeddableSandbox","initialState":{"headers":{"Content-Security-Policy":"default-src \u0027self' https://apollo-server-landing-page.cdn.apollographql.com;"}},"hideCookieToggle":false,"endpointIsEditable":false,"runtime":"@apollo/server@4.7.5","runTelemetry":true,"allowDynamicStyles":false};
new window.EmbeddedSandbox(
{
...embeddedSandboxConfig,
initialEndpoint,
}
);
</script>
It was a config issue with content security policy, see https://docs.nestjs.com/security/helmet
for anyone who might be interested, here is an example of how to load the new graphiql as an apollo server plugin:
https://codesandbox.io/p/sandbox/apollo-server-w-graphiql-8xbnju
we are pushing forward on adding the monaco-graphql
mode that I created as well for 4.0.0
I just spent a good 2 days of my life that I will never get back trying to figure this out -- the config in the nestjs docs worked beautifully. Thank you!
@johnson-elugbadebo oh man thanks this works so fine!
This issue pertains to the following package(s):
What OS and OS version are you experiencing the issue(s) on?
MacOS 10.15.6 (Catalina), all browsers.
What version of graphql-playground(-electron/-middleware) are you experiencing the issue(s) on?
latest
What is the expected behavior?
I would expect to load the GraphQL playground.
What is the actual behavior?
Stuck at "Loading GraphQL Playground" screen with the following errors in console:
What steps may we take to reproduce the behavior?
Attempt to visit graphql-playground.
Please provide a gif or image of the issue for a quicker response/fix.