是否可以通过限制require
的使用来require
npm模块?
例如,一个应用程序可以提供一个系统来扩展它的一些功能,方法是提供(作为上传可能)一个npm模块来完成一个给定的合同(说它导出一个类使用方法process
)。该模块,如果它知道应用的源代码require
它可能require('db').connect().flush()
或类似的东西。
此应用扩展程序可能会require
来自其主机的任何内容进行修改。 npm是否允许使用限制/安全方法来处理这种情况(可能通过使用进程)?
感谢。
答案 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
函数。