protobuf.js icon indicating copy to clipboard operation
protobuf.js copied to clipboard

Use of eval is strongly discouraged

Open imoye opened this issue 3 years ago • 26 comments

protobuf.js version: 6.10.2

https://rollupjs.org/guide/en/#avoiding-eval node_modules/@protobufjs/inquire/index.js

function inquire(moduleName) {
try {
        var mod = eval("quire".replace(/^/,"re"))(moduleName); // eslint-disable-line no-eval
                      ^
        if (mod && (mod.length || Object.keys(mod).length))
        return mod;

imoye avatar Jun 23 '22 03:06 imoye

+1

gunta avatar Feb 03 '23 10:02 gunta

eval() is also not available on certain environments such as Cloudflare Workers, which prevents this module, or anything that depends on it, from being used.

edevil avatar May 12 '23 11:05 edevil

Getting these errors during a Vite build:

00:22:03  common/temp/node_modules/.pnpm/@[email protected]/node_modules/@protobufjs/inquire/index.js (12:18) Use of eval in "common/temp/node_modules/.pnpm/@[email protected]/node_modules/@protobufjs/inquire/index.js" is strongly discouraged as it poses security risks and may cause issues with minification.
00:23:24  common/temp/node_modules/.pnpm/@[email protected]/node_modules/@protobufjs/inquire/index.js (12:18) Use of eval in "common/temp/node_modules/.pnpm/@[email protected]/node_modules/@protobufjs/inquire/index.js" is strongly discouraged as it poses security risks and may cause issues with minification.
00:24:32  common/temp/node_modules/.pnpm/@[email protected]/node_modules/@protobufjs/inquire/index.js (12:18) Use of eval in "common/temp/node_modules/.pnpm/@[email protected]/node_modules/@protobufjs/inquire/index.js" is strongly discouraged as it poses security risks and may cause issues with minification.
00:24:42  common/temp/node_modules/.pnpm/@[email protected]/node_modules/@protobufjs/inquire/index.js (12:18) Use of eval in "common/temp/node_modules/.pnpm/@[email protected]/node_modules/@protobufjs/inquire/index.js" is strongly discouraged as it poses security risks and may cause issues with minification.

kaiyoma avatar Jun 23 '23 15:06 kaiyoma

It's not entirely clear why this is needed at all? Why not var mod = require(moduleName);?

oleksandr-dukhovnyy avatar Jul 26 '23 08:07 oleksandr-dukhovnyy

Hi Protobufjs team! Are you planning on removing the usage of eval in the near future?

Assafz1983 avatar Aug 17 '23 10:08 Assafz1983

Same goes for Chrome Extensions using Manifest V3 - where it's also forbidden to use eval

tsemachh avatar Aug 31 '23 07:08 tsemachh

☝🏽 absolutely, had to patch to run on MV3.

whizzzkid avatar Sep 12 '23 06:09 whizzzkid

This is a huge issue for us as the page we are integrating into forbids eval via CSP

davideberlein avatar Sep 19 '23 07:09 davideberlein

same here

AntiMoron avatar Oct 09 '23 08:10 AntiMoron

https://github.com/protobufjs/protobuf.js/pull/1941

I give it a try, more tests are needed.

AntiMoron avatar Oct 09 '23 09:10 AntiMoron

In addition to the Vite errors, this issue causes runtime CSP errors in Firefox:

Content-Security-Policy: The page’s settings blocked the loading of a resource at eval (“script-src”).

Clicking the link in the browser console error takes you here:

image

kaiyoma avatar Dec 07 '23 18:12 kaiyoma

I use this patch-package file:

patches/protobufjs+7.2.5.patch
diff --git a/node_modules/protobufjs/dist/light/protobuf.js b/node_modules/protobufjs/dist/light/protobuf.js
index 5727c45..3004e3d 100644
--- a/node_modules/protobufjs/dist/light/protobuf.js
+++ b/node_modules/protobufjs/dist/light/protobuf.js
@@ -876,6 +876,10 @@ module.exports = inquire;
  * @returns {?Object} Required module if available and not empty, otherwise `null`
  */
 function inquire(moduleName) {
+    // Don't use eval with CSP in a browser: https://github.com/protobufjs/protobuf.js/pull/1548
+    if (typeof document !== "undefined") {
+        return null;
+    }
     try {
         var mod = eval("quire".replace(/^/,"re"))(moduleName); // eslint-disable-line no-eval
         if (mod && (mod.length || Object.keys(mod).length))
diff --git a/node_modules/protobufjs/dist/minimal/protobuf.js b/node_modules/protobufjs/dist/minimal/protobuf.js
index 87e6f55..d5e2d9e 100644
--- a/node_modules/protobufjs/dist/minimal/protobuf.js
+++ b/node_modules/protobufjs/dist/minimal/protobuf.js
@@ -658,6 +658,10 @@ module.exports = inquire;
  * @returns {?Object} Required module if available and not empty, otherwise `null`
  */
 function inquire(moduleName) {
+    // Don't use eval with CSP in a browser: https://github.com/protobufjs/protobuf.js/pull/1548
+    if (typeof document !== "undefined") {
+        return null;
+    }
     try {
         var mod = eval("quire".replace(/^/,"re"))(moduleName); // eslint-disable-line no-eval
         if (mod && (mod.length || Object.keys(mod).length))
diff --git a/node_modules/protobufjs/dist/protobuf.js b/node_modules/protobufjs/dist/protobuf.js
index cda26c5..012e2f5 100644
--- a/node_modules/protobufjs/dist/protobuf.js
+++ b/node_modules/protobufjs/dist/protobuf.js
@@ -876,6 +876,10 @@ module.exports = inquire;
  * @returns {?Object} Required module if available and not empty, otherwise `null`
  */
 function inquire(moduleName) {
+    // Don't use eval with CSP in a browser: https://github.com/protobufjs/protobuf.js/pull/1548
+    if (typeof document !== "undefined") {
+        return null;
+    }
     try {
         var mod = eval("quire".replace(/^/,"re"))(moduleName); // eslint-disable-line no-eval
         if (mod && (mod.length || Object.keys(mod).length))
diff --git a/node_modules/protobufjs/src/util.js b/node_modules/protobufjs/src/util.js
index 6c50899..bd9a61d 100644
--- a/node_modules/protobufjs/src/util.js
+++ b/node_modules/protobufjs/src/util.js
@@ -199,6 +199,7 @@ util.setProperty = function setProperty(dst, path, value) {
     return setProp(dst, path, value);
 };
 
+if (!util.hasOwnProperty("decorateRoot")){
 /**
  * Decorator root (TypeScript).
  * @name util.decorateRoot
@@ -210,3 +211,4 @@ Object.defineProperty(util, "decorateRoot", {
         return roots["decorated"] || (roots["decorated"] = new (require("./root"))());
     }
 });
+}

The if (!util.hasOwnProperty("decorateRoot")) part is to prevent an error of re-defining the same property when using HMR.

ngbrown avatar Jan 25 '24 05:01 ngbrown

To try to move forward with this and close the Content Security Policy threads like #997, could some maintainer explain what problem the usage of eval inside inquire resolves precisely?

❓ Maybe the problem is no longer relevant?

By doing some archeology, it seems that eval was shipped many years ago due to webpack 4 automagically bundling Buffer for the web when it noticed require.

Note that webpack 5 (released Nov 2020) has broke compat on this, and longer automagically ships nodejs polyfills.

So if that's the only reason, I'd suggest to cut a major version of protobufjs (8.0), and remove the usage of eval.

  • https://webpack.js.org/blog/2020-10-10-webpack-5-release/#automatic-nodejs-polyfills-removed

  • https://webpack.js.org/migrate/5/

  • https://stackoverflow.com/questions/64557638/how-to-polyfill-node-core-modules-in-webpack-5

jakub-g avatar Feb 14 '24 10:02 jakub-g

Any updates? This completely breaks packaging ESM package because require is not defined and this eval is always running it.

KAMAELUA avatar Mar 15 '24 12:03 KAMAELUA

I also got the problem while using @opentelemetry/exporter-trace-otlp-proto so I switch to @opentelemetry/exporter-trace-otlp-http. Less performant, but more secure at least...

alaingiller avatar Mar 28 '24 14:03 alaingiller