14 thoughts on “Calling Function or eval should be eliminated as a security measure and would cause the application execution to be halted if the document CSP header has script-src ‘self’;

  1. @evilebottnawi let me rephrase my question:
    In what case (1,eval)("this") will be executed? isn’t Function("return this")() is healthy enough way to return the global context without using eval? if Function("return this")() fails, it’s more likely there’s something wrong with the browser, so why trying to return the global context using (1,eval)("this")? I find this as an overkill way to obtain the global context, not quite justified as a need but as a “do whatever it takes” approach

  2. Can we have some provision to avoid evals in build totally. I tried same code with browserify and vueify which was earlier build with webpack and vue-loader and I found exactly 0 issues of eval or function constructor.

  3. The Vue documentation describes how “On the other hand, the runtime-only build is fully CSP-compliant. When using the runtime-only build with Webpack + vue-loader or Browserify + vueify, your templates will be precompiled into render functions which work perfectly in CSP environments.”

    https://vuejs.org/v2/guide/installation.html#CSP-environments

    So coming from Vue, I’d expect to be able to use Webpack to bundle up mye Vue app as something that can be run in a Chrome extension.

    Edit: Using webpack 4.1.1 with an explicit override of devtool: 'inline-source-map' to disable the default eval source-map for the development environment, I’m successfully able to produce an eval-less output for both production and development environments.

  4. change your webpack.config to this:

    const path = require('path');
    module.exports = {
      devtool: "source-map",
      entry: ['babel-polyfill', path.resolve(__dirname, './yourjs.js')],
      mode: 'production',
      output: {
        path: __dirname+'/draft.iml.ru/static/main/js/',
        filename: 'yout.js'
      }
    };

    had to add devtools option.

  5. @jhuesos, I suspect this is because your webpack config does not explicitly set global to false on the node object, so it injects the global.js polyfill which uses eval/new Function.

    For instance, I was also having this problem with the default webpack config from the ‘webpack’ template for Vue CLI. So I modified the below block in build\webpack.base.conf.js:

    node: {
        // prevent webpack from injecting useless setImmediate polyfill because Vue
        // source contains it (although only uses it if it's native).
        setImmediate: false,
        // prevent webpack from injecting mocks to Node native modules
        // that does not make sense for the client
        dgram: 'empty',
        fs: 'empty',
        net: 'empty',
        tls: 'empty',
        child_process: 'empty',
        // prevent webpack from injecting eval / new Function through global polyfill
        global: false
    }

    For others paying attention to this thread, I am curious whether this could have performance implications as well? Is it still true that the presence of eval or new Function at all effectively causes other code on the page to lose out on a lot of JS engine optimizations? Or is this one of those things that was more true when Crockford said so, but is a little more nuanced now? I’m not seeing much conclusive analysis out there.

    I am also wondering if there might be some value to allowing an option in configuration of injecting a more “naïve” shim for the global object which omits the eval/new Function avenue but still tries the other things? I realize it won’t cover as many cases, but seems like it might be preferable under some circumstances.

  6. @jkobylec Finally a solution that solves this issue! thanks!

    For anyone else who’s still looking for a solution to remove:
    g = g || Function("return this")() || (1,eval)("this");

    Use:

    node: {
    global: false
    }
    
  7. While above solutions of turning off node.global works, there are few libraries(e.x. babel-es6-polyfill) which refer to window variable via global and thus webpack bundling fails. So to be extra cautious, define a plugin for global as well.

    {
      node: {
         global: false
      },
      plugins: [new webpack.DefinePlugin({
         global: 'window'		// Placeholder for global used in any node_modules
      })]
    }
    
  8. From what I understood, script loader NEEDS to use eval and then is incompatible with a strict script-src CSP required, and needs unsafe-inline which is not acceptable for any sensible application.

    So is it possible, at least, to add a warning about that issue in the readme?

  9. @jkobylec Finally a solution that solves this issue! thanks!

    For anyone else who’s still looking for a solution to remove:
    g = g || Function("return this")() || (1,eval)("this");

    Use:

    node: {
    global: false
    }
    

    I solved the problem by only setting devtool to “cheap-module-source-map”

Comments are closed.