限制 npm 依赖模块对 require(隔离)的使用
Posted
技术标签:
【中文标题】限制 npm 依赖模块对 require(隔离)的使用【英文标题】:Restricting an npm dependency module's usage of require (isolation) 【发布时间】:2016-09-07 08:26:39 【问题描述】:有没有办法通过限制 require
的使用来 require
一个 npm 模块?
例如,一个应用程序可以提供一个系统来扩展它的一些功能,方法是提供(作为上传可能)一个满足给定合同的 npm 模块(说它导出一个类使用方法process
)。该模块,如果它知道将require
的应用程序的源代码,它可能会require('db').connect().flush()
或类似的东西。
此应用程序扩展可以require
来自其主机的任何内容并对其进行修改。 npm 是否允许限制/安全方法来处理这种情况(可能通过使用进程)?
谢谢。
【问题讨论】:
【参考方案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"!);
;
恶意模块仍然可以解决这个问题。实际上,您的重点应该是仔细审查您使用的模块,我永远不会在产品中使用上述模块。
【讨论】:
以上是关于限制 npm 依赖模块对 require(隔离)的使用的主要内容,如果未能解决你的问题,请参考以下文章