-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CMS does not work with Content Security Policy (CSP). Requires unsafe-eval / unsafe-inline for script-src / style-src #2138
Comments
I should add that I was able to resolve some of the non-eval issues by using sha256 hashes in script-src (not the ones generated here, but only the ones Google Chrome shows when an element is blocked). The eval issue remains, however, and further inline-styles are required once you get past the initially blocked evals / inlines. edit: Because I can't get very clear error messages from Firefox or Chrome, this issue is very hard to diagnose. It seems as though the issues start with the Netlify identity widget and then continue when trying to load the CMS. The identity widget throws an script-src eval-violation in Firefox, but not in Chrome. In Chrome, the identity widget throws a style-src unsafe-inline violation, which does not show in Firefox. In Firefox, this is where the buck stops. Chrome also throws multiple inline-style errors and the eval error mentioned before. I believe that without unsafe-inline and unsafe-eval it won't be possible to run either the identity widget or the CMS. For the style-src issues I think it's down to react components' usage of inline-styles. For eval, you have to look further as it's not just eval itself, but it's also related functions. I found a discussion regarding react from 2016 and one from 2018 regarding this. In a recent e-mail conversation, Netlify have confirmed that they have a feature request to fix this, but are not actively looking into it, so for now I shall give up. I'll leave this information here for someone to revisit one day. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
I tried to create my own local version of the script. It worked until I wanted to add cloudinary with triggers the same issues. Is there a way around this ? |
I second the question, is there any way around having to add |
Hi guys... |
I think this might be related to one of the dependencies we're using #4367 (comment) |
Thanks for answer! |
No sure actually, it requires some research. We'll be happy to get a contribution for it if someone does the research on it. |
It looks like the issue might be caused by AJV creating a function at runtime to compile JSON schema into executable code. It's described here ajv-validator/ajv#406 One possible solution is to use standalone mode to compile schemas to code at build time. |
After a bit more digging, we might have a way to eliminate this problem by compiling schemas during build time. On https://github.com/netlify/netlify-cms/blob/dbf2920254fb3682e12463a6df8ded4b94b55be0/packages/netlify-cms-core/src/constants/configSchema.js#L364, we'd need to use compiled schema. To compile schema, we can use AJV Standalone to create executable code that we store as a JavaScript module. There is a Webpack loader that can be used to take care of some of this, but this loader is using It looks like the game plan here would be,
|
…xtendDefaultPlugins (decaporg#2138)
…xtendDefaultPlugins (decaporg#2138)
…xtendDefaultPlugins (decaporg#2138)
…xtendDefaultPlugins (decaporg#2138)
…xtendDefaultPlugins (decaporg#2138)
@erezrokah After doing some more digging, coding, and research, we're really close on this, but there is one final stumble that we're hitting. We were able to completely extract the schema, and build the Unfortunately, registering widgets happens in the browser, and so it cannot be known at build-time what the complete schema will be including widget extensions. It seems to me that the only way this can work correctly is to deprecate registration of pieces of schema along with widgets and instead make the schema for user-supplied widgets sufficiently broad to type-check against any widget config. That's a breaking change and would mean slightly less type-safety for config.yaml, but it also means that it can be deployed with a secure content policy because the entire schema would be known at build time. We're investing so much effort in this because we really like Netlify CMS, but |
Thanks for the additional information @cowboyd and effort you're putting into this. Is there a way to put this change behind an option? We could always generate the static schema during build, the generate the dynamic schema by default, or let users opt out of the last part if they'd like. I also added this to #5652 |
A compromise option that might be viable is to only do dynamic validation if we detect that we need to because there are widgets registered with custom schemas. Widgets registered that do not have any additional schema would not require any dynamic validation. // defined at build time
import { staticValidateConfig } from './config.schema.json';
export function validateConfig(config) {
if (Object.values(getWidgetSchemas().find(schema => !!Object.keys(schema)))) {
// there are custom widget schemas, we can't use the static validation
// this is the current `validateConfig` function.
// this will trigger a CSP error unless `unsafe-eval` is set.
return dynamicValidateConfig(config)
} else {
return staticValidateConfig(config);
}
} It's a bit of a strange implicit opt-out, but it does have the advantage of being backwards compatible. |
I like that idea @cowboyd 💡 ! |
@erezrokah I'm having a look at implementing @cowboyd 's suggestion. There are a couple of places in the codebase where One is in I wonder if you could help me understand if:
Thanks for your input |
Hi 👋
We can assume it will never have a schema.
I think the schemas for those could be evaluated at build time, as |
@erezrokah I created a PR that includes changes implemented by @dagda1 and has all of the tests passing. There is a blocking the PR that I'll describe in a comment. |
With help from @dagda1, I created an example repo that has CSP with Netlify. I created a version of Netlify build that works with CSP. You can find it here https://github.com/taras/create-react-app-csp-strict-example |
We still need iarna/iarna-toml#45 to fully eliminate eval. |
Any updates here? |
Describe the bug
I have been using Netlify CMS for sites without a content security policy. I am now trying to increase the security of my sites by adding this.
The CSP requires defining what sources are allowed for scripts, styles, frames, objects, etc.
The CSP also blocks things like eval in any JS execution and also generally inline-scripts or styles.
While it is possible to globally allow these things by setting unsafe-inline or unsafe-eval as permitted, this is not recommended, as it defeats the purpose of the CSP.
Here is the CSP I am applying to one of my sites via special file that Netlify recognises on deploy:
As you can see, I have already attempted to somehow make anything coming from Netlify permissible, but Firefox states (among other things):
Content Security Policy: The page’s settings blocked the loading of a resource at eval (“script-src”)
Content Security Policy: The page’s settings blocked the loading of a resource at inline (“script-src”)
To Reproduce
Deploy any site to Netlify with a Content Security Policy which does not permit unsafe-eval or unsafe-inline
Expected behavior
Once Netlify has been added as permitted source for scripts, styles, etc. for this to allow loading the CMS. This may require a way to load the Netlify CMS without an inline-script tag, but I am not seeing this issue with other scripts, like google tag manager.
Eval may be a bigger issue, as that would require a change to the CMS' code and eval maybe unavoidable.
Applicable Versions:
Tested on:
CMS configuration
not relevant for this, presumably
The text was updated successfully, but these errors were encountered: