Creating a simple template electron app. I want to do a fetch request to my api but am continuously stopped by the Content Security Policy errors and I have no idea how to fix them.
Refused to connect to 'https://api.myapp.com/' because it violates the following Content Security Policy directive: "default-src 'self' 'unsafe-inline' data:". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.
index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-eval' ">
<meta charset="UTF-8">
</head>
<body>
<div id="root"></div>
</body>
</html>
app.js
const handleSubmit = async () => {
const response = await fetch("https://api.myapp.com/books", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
return response.json();
};
I have tried adding the api address to the existing policy, and adding additional policies but nothing works.
CodePudding user response:
In the violation message you have a whitelist: Refused to connect to ... the following Content Security Policy directive: "default-src 'self' 'unsafe-inline' data:".
But in the meta tag you shown a different whitelist: default-src 'self' 'unsafe-eval'.
This means you have at least 2 CSPs in action. Several CSPs act as consistent filters - all sources intended to be allowed should pass all filters. As result a toughest rules from all CSP are applied.
Figure out where do you publish a first CSP and add connect-src https://api.myapp.com
into it. And remove CSP in the meta tag.
Most likely it's some package publishes his default CSP via HTTP header (how to check), so the Helmet is under suspicion - it publishes default CSP since v4.
Of course you can publish CSP HTTP header directly with code like:
session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
callback({ responseHeaders: Object.assign({
...details.responseHeaders,
"Content-Security-Policy": [ "default-src 'self' 'unsafe-inline' data:" ]
}, details.responseHeaders)});
});
CodePudding user response:
I found the answer to this. It seems that Webpack uses a default Content Security Policy for developer mode which can be overridden in the package.json.
Taken from webpack WebpackPluginRendererConfig
/**
* Sets the [`Content-Security-Policy` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)
* for the Webpack development server.
*
* Normally you would want to only specify this as a `<meta>` tag. However, in development mode,
* the Webpack plugin uses the `devtool: eval-source-map` source map setting for efficiency
* purposes. This requires the `'unsafe-eval'` source for the `script-src` directive that wouldn't
* normally be recommended to use. If this value is set, make sure that you keep this
* directive-source pair intact if you want to use source maps.
*
* Default: `default-src 'self' 'unsafe-inline' data:;`
* `script-src 'self' 'unsafe-eval' 'unsafe-inline' data:`
*/
devContentSecurityPolicy?: string;
By setting devContentSecurityPolicy in package.json I can set my own Content Security Policy.
"plugins": [
[
"@electron-forge/plugin-webpack",
{
"mainConfig": "./webpack.main.config.js",
"devContentSecurityPolicy": "connect-src 'self' https://api.myapp.com 'unsafe-eval'",
"renderer": {
"config": "./webpack.renderer.config.js",
"entryPoints": [
{
"html": "./src/index.html",
"js": "./src/renderer.ts",
"name": "main_window"
}
]
}
}
]
]
Note: Changing this and saving wont update the policy in the app. You need to stop and run 'npm start' again to apply these changes.