webpack / webpack-dev-server

Serves a webpack app. Updates the browser on changes. Documentation https://webpack.js.org/configuration/dev-server/.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

5.0 dev server requires 'unsafe-eval' script-src in CSP

bhollis opened this issue · comments

Bug report

Our project (https://github.com/DestinyItemManager/DIM) includes our Content-Security-Policy header in the dev server, to allow us to catch CSP problems while developing locally. Prior to webpack-dev-server v5.0.0, this worked fine without the 'unsafe-eval' script-src permission, but now it requires it. (Note: We also have client: { overlay: false } set).

Actual Behavior

Our JS fails to load because our CSP header does not include 'unsafe-eval':

index.js:1414 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' https://*.googletagmanager.com https://*.google-analytics.com https://opencollective.com".

    at new Function (<anonymous>)
    at SyncBailHookCodeFactory.create (index.js:1414:1)
    at Hook.COMPILE [as compile] (index.js:2377:1)
    at Hook._createCall (index.js:1108:1)
    at Hook.CALL_DELEGATE (index.js:1068:1)
    at WebpackLogger.<anonymous> (index.js:3513:1)
    at WebpackLogger.info (index.js:3067:1)
    at logEnabledFeatures (log.js:33:1)
    at ./node_modules/.pnpm/webpack-dev-server@5.0.0_quill-delta@5.1.0_rxjs@7.8.1_tslib@2.6.2_webpack-cli@5.1.4_webpack@5.90.1/node_modules/webpack-dev-server/client/index.js?protocol=wss%3A&hostname=localhost&port=8080&pathname=%2Fws&logging=info&overlay=false&reconnect=10&hot=only&live-reload=false (index.js:131:19)
    at options.factory (react refresh:6:1)

Expected Behavior

At least with the overlay disabled, webpack-dev-server shouldn't rely on 'unsafe-eval', however it managed to do so before.

How Do We Reproduce?

Our Webpack config is here:
https://github.com/DestinyItemManager/DIM/blob/master/config/webpack.ts#L112-L152

I'd suggest a minimal repro would be a project with client: { overlay: false } that customizes the dev server headers to include 'Content-Security-Policy': "default-src 'self'".

Please paste the results of npx webpack-cli info here, and mention other relevant information

System:
OS: macOS 14.0
CPU: (10) arm64 Apple M1 Max
Memory: 130.56 MB / 64.00 GB
Binaries:
Node: 21.4.0 - /opt/homebrew/bin/node
npm: 10.2.4 - /opt/homebrew/bin/npm
Browsers:
Chrome: 121.0.6167.160
Safari: 17.0
Packages:
babel-loader: ^9.1.3 => 9.1.3
clean-webpack-plugin: ^4.0.0 => 4.0.0
compression-webpack-plugin: ^11.0.0 => 11.0.0
copy-webpack-plugin: ^12.0.2 => 12.0.2
css-loader: ^6.10.0 => 6.10.0
css-modules-typescript-loader: ^4.0.1 => 4.0.1
fork-ts-checker-notifier-webpack-plugin: ^5.0.0 => 5.0.0
fork-ts-checker-webpack-plugin: ^6.0.1 => 6.5.3
generate-json-webpack-plugin: ^2.0.0 => 2.0.0
html-loader: ^5.0.0 => 5.0.0
html-webpack-plugin: ^5.6.0 => 5.6.0
lodash-webpack-plugin: ^0.11.6 => 0.11.6
markdown-loader: ^8.0.0 => 8.0.0
postcss-assets-webpack-plugin: ^4.1.2 => 4.1.2
postcss-loader: ^8.1.0 => 8.1.0
sass-loader: ^14.1.0 => 14.1.0
source-map-loader: ^5.0.0 => 5.0.0
style-loader: ^3.3.4 => 3.3.4
svgo-loader: ^4.0.0 => 4.0.0
terser-webpack-plugin: ^5.3.10 => 5.3.10
ts-loader: ^9.5.1 => 9.5.1
tsconfig-paths-webpack-plugin: ^4.1.0 => 4.1.0
webpack: ^5.90.1 => 5.90.1
webpack-cli: ^5.1.4 => 5.1.4
webpack-dev-server: ^5.0.0 => 5.0.0
webpack-notifier: ^1.15.0 => 1.15.0
webpack-stats-plugin: ^1.1.3 => 1.1.3
workbox-webpack-plugin: 7.0.0 => 7.0.0

I'd suggest a minimal repro would be a project with client: { overlay: false } that customizes the dev server headers to include 'Content-Security-Policy': "default-src 'self'".

Can you create the same and share it using codesandbox/stackblitz/github?

I'm having the same issue. Hopefully I can add some more useful context to the conversation.

This is my devServer config, though i imagine the only real relevant part is the Content-Security-Policy header part:

devServer: {
  port: process.env.PORT || 8080,
  host: "0.0.0.0",
  allowedHosts: "all",
  devMiddleware: { stats: "minimal" },
  client: { logging: "warn", webSocketURL: process.env.WEBPACK_WEBSOCKET_URL },
  historyApiFallback: true,
  headers: [
    { key: "X-Frame-Options", value: "DENY" },
    { key: "X-Content-Type-Options", value: "nosniff" },
    { key: "X-XSS-Protection", value: "1; mode=block" },
    {
      key: "Content-Security-Policy",
      value: "base-uri 'none'; object-src 'none'; script-src 'self'; frame-ancestors 'none'",
    },
  ],
},

This stack trace is probably next to useless but the top of the stack is in the module node_modules/tapable/lib/HookCodeFactory.js calling new Function.

create https://app.local/:5651
COMPILE https://app.local/:6614
_createCall https://app.local/:5345
CALL_DELEGATE https://app.local/:5305
getLogger https://app.local/:7750
info https://app.local/:7304
logEnabledFeatures https://app.local/:8793
475040 https://app.local/:4048
factory https://app.local/:684
__webpack_require__ https://app.local/:26
__webpack_exec__ https://app.local/:13108
<anonymous> https://app.local/:13109
webpackJsonpCallback https://app.local/:1349
<anonymous> https://app.local/:1402
app.local:5651:16
create https://app.local/:5651
COMPILE https://app.local/:6614
_createCall https://app.local/:5345
CALL_DELEGATE https://app.local/:5305
getLogger https://app.local/:7750
info https://app.local/:7304
logEnabledFeatures https://app.local/:8793
475040 https://app.local/:4048
factory https://app.local/:684
__webpack_require__ https://app.local/:26
__webpack_exec__ https://app.local/:13108
<anonymous> https://app.local/:13109
webpackJsonpCallback https://app.local/:1349
<anonymous> https://app.local/:1402

I did some digging and apparently this issue has come up in the past in #3078. Maybe the name of the module in tapable has changed and one would just need to update this line:

/^tapable\/lib\/SyncBailHook/,