限制npm依赖模块使用require(隔离)

时间:2016-05-11 18:50:54

标签: javascript node.js security npm require

是否可以通过限制require的使用来require npm模块?

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

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

感谢。

2 个答案:

答案 0 :(得分:0)

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"!); 
};

恶意模块仍然可以解决这个问题。实际上你的重点应该是仔细审查你使用的模块,我不会在上面使用它。

答案 1 :(得分:0)

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函数。