webpack-hot-client
webpack-hot-client copied to clipboard
Bundled code includes `eval()`, requiring a relaxed CSP
- Operating System: OSX
- Node Version: 8.11.3
- NPM Version: [email protected]
- webpack Version: 4.9.2
- webpack-hot-client Version: 4.1.1
Expected Behavior
Webpack hot client should be able to work without requiring an 'unsafe-eval'
CSP.
Actual Behavior
I think that requiring the "dist" version of loglevelnext
like this results in bundling code with eval()
'd modules:
https://github.com/webpack-contrib/webpack-hot-client/blob/0ac06733c7eafdd8f1a89dea2c2df9000de9a70b/lib/client/log.js#L2
Snippet from the resulting bundle:
/***/ "./lib/LogLevel.js":
/*!*************************!*\
!*** ./lib/LogLevel.js ***!
\*************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
eval("\n/* global window: true */\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nvar PrefixFactory = __webpack_require__(/*! ../factory/PrefixFactory */ \"./factory/PrefixFactory.js\");\n\nvar MethodFactory = __webpack_require__(/*! ./MethodFactory */ \"./lib/MethodFactory.js\");\n\nvar defaults = {\n factory: null,\n level: 'warn',\n name: +new Date(),\n prefix: null\n};\n\nmodule.exports =\n/*#__PURE__*/\nfunction () {\n function LogLevel(options) {\n _classCallCheck(this, LogLevel);\n\n // implement for some _very_ loose type checking. avoids getting into a\n // circular require between MethodFactory and LogLevel\n this.type = 'LogLevel';\n this.options = Object.assign({}, defaults, options);\n this.methodFactory = options.factory;\n\n if (!this.methodFactory) {\n var factory = options.prefix ? new PrefixFactory(this, options.prefix) : new MethodFactory(this);\n this.methodFactory = factory;\n }\n\n if (!this.methodFactory.logger) {\n this.methodFactory.logger = this;\n }\n\n this.name = options.name || '<unknown>'; // this.level is a setter, do this after setting up the factory\n\n this.level = this.options.level;\n }\n\n _createClass(LogLevel, [{\n key: \"disable\",\n value: function disable() {\n this.level = this.levels.SILENT;\n }\n }, {\n key: \"enable\",\n value: function enable() {\n this.level = this.levels.TRACE;\n }\n }, {\n key: \"factory\",\n get: function get() {\n return this.methodFactory;\n },\n set: function set(factory) {\n factory.logger = this;\n this.methodFactory = factory;\n this.methodFactory.replaceMethods(this.level);\n }\n }, {\n key: \"level\",\n get: function get() {\n return this.currentLevel;\n },\n set: function set(logLevel) {\n var level = this.methodFactory.distillLevel(logLevel);\n\n if (level == null) {\n throw new Error(\"loglevelnext: setLevel() called with invalid level: \".concat(logLevel));\n }\n\n this.currentLevel = level;\n this.methodFactory.replaceMethods(level);\n\n if (typeof console === 'undefined' && level < this.levels.SILENT) {\n // eslint-disable-next-line no-console\n console.warn('loglevelnext: console is undefined. The log will produce no output.');\n }\n }\n }, {\n key: \"levels\",\n get: function get() {\n // eslint-disable-line class-methods-use-this\n return this.methodFactory.levels;\n }\n }]);\n\n return LogLevel;\n}();\n\n//# sourceURL=webpack://log/./lib/LogLevel.js?");
/***/ }),
I'm not sure off the top of my head why the dist specifically is being require'd instead of require("loglevelnext")
(which I don't think would have this problem).
I know it's probably a little unusual to set a CSP like this in development, but it reflects the way that the code is run in production.
How Do We Reproduce?
Set a CSP that prohibits 'unsafe-eval'
.
There's https://github.com/webpack-contrib/webpack-log which might just supersede the direct use of loglevelnext
in this project regardless.
Friendly ping -- is this something you'd be open to a PR for?