Skip to content
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

[webpack] Add a configuration option to set the CSP header during development #2331

Closed
3 tasks done
malept opened this issue Jun 18, 2021 · 17 comments · Fixed by #2332
Closed
3 tasks done

[webpack] Add a configuration option to set the CSP header during development #2331

malept opened this issue Jun 18, 2021 · 17 comments · Fixed by #2332

Comments

@malept
Copy link
Member

malept commented Jun 18, 2021

Preflight Checklist

  • I have read the contribution documentation for this project.
  • I agree to follow the code of conduct that this project follows, as appropriate.
  • I have searched the issue tracker for a feature request that matches the one I want to file, without success.

Problem Description

Extracted from #2289:

Webpack property devtool default not playing nice with content-security-policy

The new implementation of the devtool-property in the webpack config doesn't work with the following HTML tag: <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'"> since that prevents execution from eval that is being run somewhere in the defaults of webpack.

Proposed Solution

Add a top-level Webpack plugin configuration option to customize the CSP header sent by webpack-dev-server.

Alternatives Considered

Again, from #2289:

Manually set devtool: 'source-map' for the renderer process

This isn't ideal for a couple of reasons:

  1. source-map is slower to generate than eval-source-map (or so I'm told)
  2. This puts the onus on the app developer to know about this Webpack configuration option, and I'd prefer to avoid that.

Additional Information

Please note that app developers still need to set the <meta> tag appropriately, for when the Electron app is bundled and distributed.

This will probably also need documentation on the website.

@malept malept changed the title [webpack] Add a configuration option to set the CSP header during development. [webpack] Add a configuration option to set the CSP header during development Jun 18, 2021
@Eli-Black-Work
Copy link

@malept, FYI, when we upgraded from 6.0.0-beta.57 to 6.0.0-beta.58 our app stopped working in development mode but works in production mode.

It appears that the default CSP headers in production mode allow for making requests to other domains (for example, we do POST requests to www.example.com), but the default CSP headers in development mode don't allow this.

@malept
Copy link
Member Author

malept commented Jul 26, 2021

I'm unlikely to change this. In fact, I'm probably going to add default CSP headers to all of the templates, to match electron-quick-start.

@UnsignedInt8
Copy link

@malept, FYI, when we upgraded from 6.0.0-beta.57 to 6.0.0-beta.58 our app stopped working in development mode but works in production mode.

It appears that the default CSP headers in production mode allow for making requests to other domains (for example, we do POST requests to www.example.com), but the default CSP headers in development mode don't allow this.

Add devContentSecurityPolicy to forge.config.js like this:

plugins: [
    [
      '@electron-forge/plugin-webpack',
      {
        devContentSecurityPolicy: `default-src * self blob: data: gap:; style-src * self 'unsafe-inline' blob: data: gap:; script-src * 'self' 'unsafe-eval' 'unsafe-inline' blob: data: gap:; object-src * 'self' blob: data: gap:; img-src * self 'unsafe-inline' blob: data: gap:; connect-src self * 'unsafe-inline' blob: data: gap:; frame-src * self blob: data: gap:;`,
        mainConfig: './webpack.main.config.js',
        renderer: {
          config: './webpack.renderer.config.js',
          entryPoints: [
            {
              html: './src/index.html',
              js: './src/renderer.ts',
              name: 'main_window',
              preload: {
                js: './src/preload.ts',
              },
            },
          ],
        },
      },
    ],
  ]

@Eli-Black-Work
Copy link

I'm unlikely to change this. In fact, I'm probably going to add default CSP headers to all of the templates, to match electron-quick-start.

Yes, just letting you know 🙂

@Eli-Black-Work
Copy link

@malept, FYI, when we upgraded from 6.0.0-beta.57 to 6.0.0-beta.58 our app stopped working in development mode but works in production mode.
It appears that the default CSP headers in production mode allow for making requests to other domains (for example, we do POST requests to www.example.com), but the default CSP headers in development mode don't allow this.

Add devContentSecurityPolicy to forge.config.js like this:

plugins: [
    [
      '@electron-forge/plugin-webpack',
      {
        devContentSecurityPolicy: `default-src * self blob: data: gap:; style-src * self 'unsafe-inline' blob: data: gap:; script-src * 'self' 'unsafe-eval' 'unsafe-inline' blob: data: gap:; object-src * 'self' blob: data: gap:; img-src * self 'unsafe-inline' blob: data: gap:; connect-src self * 'unsafe-inline' blob: data: gap:; frame-src * self blob: data: gap:;`,
        mainConfig: './webpack.main.config.js',
        renderer: {
          config: './webpack.renderer.config.js',
          entryPoints: [
            {
              html: './src/index.html',
              js: './src/renderer.ts',
              name: 'main_window',
              preload: {
                js: './src/preload.ts',
              },
            },
          ],
        },
      },
    ],
  ]

Thanks! 🙂

@Deliaz
Copy link

Deliaz commented Sep 16, 2021

@malept, FYI, when we upgraded from 6.0.0-beta.57 to 6.0.0-beta.58 our app stopped working in development mode but works in production mode.

It appears that the default CSP headers in production mode allow for making requests to other domains (for example, we do POST requests to www.example.com), but the default CSP headers in development mode don't allow this.

Sounds like a breaking change.
My project was also broke after the update.

@malept
Copy link
Member Author

malept commented Sep 16, 2021

I empathize, but changes like this are why v6 is still in beta. As such, semver rules don't really apply here. Moving forward the release notes should mention when a breaking change occurs (for example, beta 60).

@Deliaz
Copy link

Deliaz commented Sep 16, 2021

I see, thank you for the reply!

Let me leave a message here to someone who might have the same problem.

I have an Electron project which uses electron-forge and Firebase Auth.
After updating I wasn't able to sign in, getting this error:

Refused to connect to 'https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword...' 
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

FirebaseError: Firebase: Error (auth/network-request-failed).

Setting devContentSecurityPolicy from #2331 (comment) fixed the problem.

@joezappie
Copy link

joezappie commented Oct 19, 2021

This doesn't seem to work for me (but I'm probably just doing something wrong). Just upgraded to ^6.0.0-beta.61 and added it into my package.json:

"plugins": [
        [
          "@electron-forge/plugin-webpack",
          {
            "mainConfig": "./webpack.main.config.js",
            "devContentSecurityPolicy": "default-src * self blob: data: gap:; style-src * self 'unsafe-inline' blob: data: gap:; script-src * 'self' 'unsafe-eval' 'unsafe-inline' blob: data: gap:; object-src * 'self' blob: data: gap:; img-src * self 'unsafe-inline' blob: data: gap:; connect-src self * 'unsafe-inline' blob: data: gap:; frame-src * self blob: data: gap:;",
            "renderer": {
              "config": "./webpack.renderer.config.js",
              "entryPoints": [
                {
                  "html": "./src/app/index.html",
                  "js": "./src/app/renderer.js",
                  "name": "main_window",
                  "preload": {
                    "js": "./src/preload.js"
                  }
                }
              ]
            }
          }
        ]
      ]

Running my electron forge app with "npm start" still gives me the CSP warning. I'm a bit confused on how this is supposed to work, should it be injecting a element into the page? Adding my own doesn't get overwritten either.

@Eli-Black-Work
Copy link

@jrj2211 I seem to remember that there was a reason that people were using backticks instead of double quotes around the value for devContentSecurityPolicy.

So you probably should use this:

`default-src * self blob: data: gap:; style-src * self 'unsafe-inline' blob: data: gap:; script-src * 'self' 'unsafe-eval' 'unsafe-inline' blob: data: gap:; object-src * 'self' blob: data: gap:; img-src * self 'unsafe-inline' blob: data: gap:; connect-src self * 'unsafe-inline' blob: data: gap:; frame-src * self blob: data: gap:;

instead of this:

"default-src * self blob: data: gap:; style-src * self 'unsafe-inline' blob: data: gap:; script-src * 'self' 'unsafe-eval' 'unsafe-inline' blob: data: gap:; object-src * 'self' blob: data: gap:; img-src * self 'unsafe-inline' blob: data: gap:; connect-src self * 'unsafe-inline' blob: data: gap:; frame-src * self blob: data: gap:;"

Hope that helps 🙂

@m4tta
Copy link

m4tta commented Dec 22, 2021

Whatever is going on here completely broke the ability to load local files using the file:// protocol along with protocol.registerFileProtocol I've tried everything possible under the sun inside "devContentSecurityPolicy" I've googled every least restrictive allow anything CSP thing I could find.

Edit: just putting a blank string did the trick... What a nightmare. I wasted 2 nights trying to just get an image to load from a local path. I couldn't just import it for what I am doing.

@vladkrutenyuk
Copy link

@malept, FYI, when we upgraded from 6.0.0-beta.57 to 6.0.0-beta.58 our app stopped working in development mode but works in production mode.
It appears that the default CSP headers in production mode allow for making requests to other domains (for example, we do POST requests to www.example.com), but the default CSP headers in development mode don't allow this.

Add devContentSecurityPolicy to forge.config.js like this:

plugins: [
    [
      '@electron-forge/plugin-webpack',
      {
        devContentSecurityPolicy: `default-src * self blob: data: gap:; style-src * self 'unsafe-inline' blob: data: gap:; script-src * 'self' 'unsafe-eval' 'unsafe-inline' blob: data: gap:; object-src * 'self' blob: data: gap:; img-src * self 'unsafe-inline' blob: data: gap:; connect-src self * 'unsafe-inline' blob: data: gap:; frame-src * self blob: data: gap:;`,
        mainConfig: './webpack.main.config.js',
        renderer: {
          config: './webpack.renderer.config.js',
          entryPoints: [
            {
              html: './src/index.html',
              js: './src/renderer.ts',
              name: 'main_window',
              preload: {
                js: './src/preload.ts',
              },
            },
          ],
        },
      },
    ],
  ]

THANK YOU !!!!!! it works))

@janwendt
Copy link

janwendt commented Feb 9, 2023

I just started a new Electron Forge project with the webpack-typescript template and got the warning:

Electron Security Warning (Insecure Content-Security-Policy) This renderer process has either no Content Security
  Policy set or a policy with "unsafe-eval" enabled. This exposes users of
  this app to unnecessary security risks.

I did some research and then added:
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
to my index.html to get rid of the warning. But then i got the error:

Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'".

So i finally discovered this issue here and set devContentSecurityPolicy in my forge.config.ts as described above but that did not solve the problem for me. Anything i am missing?

@Eli-Black-Work
Copy link

Eli-Black-Work commented Feb 13, 2023

@janwendt Can you post some code showing how you set devContentSecurityPolicy?

@moepmoep12
Copy link

moepmoep12 commented Feb 23, 2023

Same problem as @janwendt. Added property devContentSecurityPolicy to forge.config.ts:

  plugins: [
    new WebpackPlugin({
      devContentSecurityPolicy: `default-src * self blob: data: gap:; style-src * self 'unsafe-inline' blob: data: gap:; script-src * 'self' 'unsafe-eval' 'unsafe-inline' blob: data: gap:; object-src * 'self' blob: data: gap:; img-src * self 'unsafe-inline' blob: data: gap:; connect-src self * 'unsafe-inline' blob: data: gap:; frame-src * self blob: data: gap:;`,
      mainConfig,
      renderer: {
        config: rendererConfig,
        entryPoints: [
          // ....
        ],
      },
    }),
  ],

The warning still persists. However, when I set the CSP header in the index.html

    <meta
      http-equiv="Content-Security-Policy"
      content="script-src 'self' 'unsafe-inline'"
    />

The error occurs

Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'".

@HashedViking
Copy link

HashedViking commented Feb 3, 2024

@moepmoep12 @Eli-Black-Work @janwendt

Worked for me when I removed all CSP meta tags from index.html and put devContentSecurityPolicy at the end of config struct (see WebpackPluginConfig.ts to understand why):

 plugins: [
    new AutoUnpackNativesPlugin({}),
    new WebpackPlugin({
      mainConfig,
      renderer: {
        config: rendererConfig,
        entryPoints: [
          {
            html: './src/index.html',
            js: './src/renderer.ts',
            name: 'main_window',
            preload: {
              js: './src/preload.ts',
            },
          },
        ],
      },
      devContentSecurityPolicy: `default-src * self blob: data: gap:; style-src * self 'unsafe-inline' blob: data: gap:; script-src * 'self' 'unsafe-eval' 'unsafe-inline' blob: data: gap:; object-src * 'self' blob: data: gap:; img-src * self 'unsafe-inline' blob: data: gap:; connect-src self * 'unsafe-inline' blob: data: gap:; frame-src * self blob: data: gap:;`,
    }),

@shantanu-kulkarni
Copy link

@HashedViking @moepmoep12 I tried the same thing, removed all meta tags from the index.html and put the devContentSecurityPolicy at the end of the config in my forge.config.js yet I'm getting this error:

Refused to connect to 'ws://localhost:3000/ws' because it violates the following Content Security Policy directive: "default-src 'none'". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.

I'm a bit new to Webpack and Electron and have been trying out things to fix this but I'm persistently getting the error.
This is my forge.config.js:

plugins: [
{
name: '@electron-forge/plugin-auto-unpack-natives',
config: {},
},
{
name: '@electron-forge/plugin-webpack',
config: {
mainConfig: './webpack.main.config.js',
renderer: {
config: './webpack.renderer.config.js',
entryPoints: [
{
html: './src/index.html',
js: './src/renderer.js',
name: 'main_window',
preload: {
js: './src/preload.js',
},
},
],
},
devContentSecurityPolicy: `default-src * self blob: data: gap:; style-src * self 'unsafe-inline' blob: data: gap:; script-src * 'self' 'unsafe-eval' 'unsafe-inline' blob: data: gap:; object-src * 'self' blob: data: gap:; img-src * self 'unsafe-inline' blob: data: gap:; connect-src self * 'unsafe-inline' blob: data: gap:; frame-src * self blob: data: gap:;`,
},
},
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.