【问题标题】:Restricting an npm dependency module's usage of require (isolation)限制 npm 依赖模块对 require(隔离)的使用
【发布时间】:2016-09-07 08:26:39
【问题描述】:

有没有办法通过限制 require 的使用来 require 一个 npm 模块?

例如,一个应用程序可以提供一个系统来扩展它的一些功能,方法是提供(作为上传可能)一个满足给定合同的 npm 模块(说它导出一个类使用方法process)。该模块,如果它知道将require 的应用程序的源代码,它可能会require('db').connect().flush() 或类似的东西。

此应用程序扩展可以require 来自其主机的任何内容并对其进行修改。 npm 是否允许限制/安全方法来处理这种情况(可能通过使用进程)?

谢谢。

【问题讨论】:

    标签: javascript node.js security npm require


    【解决方案1】:

    Node.js 和 npm 都不提供沙箱模块的工具。尽管对模块的实际加载方式有一点了解,但我们可以轻松实现这样的机制。

    让我们看看,一个模块gets access to require

    一旦 require 准备好,整个加载的源代码将被包装在一个新函数中,该函数将 require、module、exports 和所有其他公开的变量作为参数。这会为该模块创建一个新的功能范围,从而不会污染 Node.js 环境的其余部分。

    其实我们可以在source code看到准确的模板:

    NativeModule.wrapper = [
        '(function (exports, require, module, __filename, __dirname) { ',
        '\n});'
    ];
    

    所以我们可以利用相同的方法,将上传的模块包装在 IIFE 中在需要它之前

    (function (exports, require, module, __filename, __dirname) {
    
        // module source
    
    }(exports, undefined /* here's the trick */, module, __filename, __dirname);
    

    现在我们可以安全地 require 封装的模块,因为它不能再访问 require 函数了。

    【讨论】:

      【解决方案2】:

      NPM 没有提供任何东西来实现这一点,但根据您的要求,您可以通过覆盖节点的 require 语句来实现某种程度的安全性。

      const MY_SECRET_TOKEN = '1234';
      const rekuire = global.require;
      global.require = function(nodeModule, token) {
        if (nodeModule !== 'db' || MY_SECRET_TOKEN === token) {
          return rekuire(nodeModule);
        }
      
        throw new Error('Unauthorized attempt to access secure module "db"!); 
      };
      

      恶意模块仍然可以解决这个问题。实际上,您的重点应该是仔细审查您使用的模块,我永远不会在产品中使用上述模块。

      【讨论】:

        猜你喜欢
        • 2015-10-24
        • 1970-01-01
        • 2023-03-29
        • 2017-12-30
        • 1970-01-01
        • 1970-01-01
        • 2016-08-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多