针对此事,我有几个问题:
1. 如何检测模块是否存在安全问题? 2. 如何防止Node.js执行恶意*.js脚本?
非常感谢您能分享任何构建node.js服务的经验。
谢谢, Jeffrey
https://github.com/yahoo/fs-lock
"该模块的目标是帮助您在加载第三方模块时限制其访问权限。"
这听起来有点像Jeffrey在Plato的回答中提出的建议。
(如果您想进一步了解如何挂钩操作系统调用,hookit项目可能会提供一些想法。虽然它目前只包装回调函数,但它可能会提供关于挂钩什么以及如何挂钩的灵感。这里是一个示例。)
2. 分析敏感数据的流动
如果您只担心数据窃取(而不是文件系统或数据库访问),那么可以将重点放在以下问题上:
您最应该关注那些传递了敏感数据的包。假设您的 Web 服务上的一些数据已经公开展示给了公众!
大多数包将无法访问您的应用程序的完整堆栈,只能访问您传递给它们的数据位。如果一个包仅传递了少量敏感数据,并且从未传递其他数据,它可能无法对其接收到的数据进行任何恶意操作。(例如,如果您将所有用户名传递给一个包进行处理,将所有地址传递给另一个包,那么这就比将所有用户名、地址和信用卡号码传递给同一个包更加安全!)
识别您的应用程序中的敏感数据,并注意它们传递到哪些模块的哪些函数中。
3. 执行高效的代码审查
您可能不需要去Github阅读代码。大多数软件包都在其安装文件夹内的node_modules
中提供所有源代码。(但有一些软件包提供二进制文件,这些自然更难验证。)为了保护你自己的应用程序,你不需要阅读项目中所有包的全部源代码。你只需要审查那些实际被调用的函数。
你可以通过阅读代码或使用基于文本的调试器或GUI调试器来跟踪代码。(当然,你应该注意分支,不同的输入可能会导致调用模块的不同部分)
在调用你不信任的模块时设置断点,这样你就可以逐步执行被调用的代码并查看它做了什么。你可能能够得出结论,只有模块的一小部分被使用,因此只需要验证那部分代码。
虽然跟踪流程应该涵盖运行时敏感数据的问题,但为了检查文件访问或数据库访问,我们还应该查看每个所需模块的初始化代码以及从那里进行的所有调用(包括require
)。
4. 其他措施
在package.json
中锁定每个包的版本号可能是明智的,这样你就不会在决定需要时意外安装新版本的包。
您可以使用社交因素来建立对包的信心。检查作者的声誉。他是谁,他为谁工作?作者及其雇主是否有声誉要维护?同样,谁使用他的项目?如果该包非常受欢迎,并被行业巨头使用,则很可能已经有其他人审查了代码。
您可能希望访问Github并通过“观察”存储库来为您正在使用的所有顶级模块启用通知。这将在将来报告包中任何漏洞时通知您。
如果您的项目依赖树足够大,审查所有依赖项不是一种可行的长期策略。
Joey的原始答案提供了一些针对特定情况可以使用的对策。我也看到过https://github.com/berstend/node-safe - 可以让您在Mac上稍微更安全一些。
然而,问题的一个通用解决方案正在形成中。
第二步需要使用Compartment,这是TC39中的一个正在进行中的工作https://github.com/tc39/proposal-compartments/
但是已经存在一个shim。并且已经在该shim之上构建了一些工具。
你可以直接使用SES-shim并实现自己的控件,或者使用LavaMoat的便利性。
LavaMoat允许您生成和调整每个包策略,您可以决定它应该访问哪些全局变量和内置变量。LavaMoat还提供了一个工具来管理安装脚本。
这是我的关于SES和LavaMoat的演讲,其中包含演示。
有关更多详细信息,请参见LavaMoat文档
npm i --ignore-scripts -D @lavamoat/allow-scripts
npx --no-install allow-scripts setup
npx --no-install allow-scripts auto
allow-scripts
npm i -D lavamoat
"scripts": {
"lavamoat-policy": "lavamoat app.js --autopolicy",
"start": "lavamoat app.js"
npm start
启动您的应用程序docker run --rm -it \
-v "$PWD:$PWD" \
-w "$PWD" \
-p "127.0.0.1:9000:9000" "node:18" bash
大多数(全部?)模块在Github上都有源代码可用,您可以阅读源代码并查找安全问题,或者聘请安全专业人员来完成工作。
我只是冒险尝试 - 尽管我倾向于使用具有数百个提交、积极维护和问题列表的流行软件包。
require
语句,因此在发生漏洞的情况下,它只能影响第二台机器(可能)。第一个应用程序将与第二个应用程序通信,但不会直接 require
任何东西(除了你需要进行通信的内容)。 - PlatoN
家公司雇用人员反复审计同一软件包的同一版本是愚蠢的。问题在于npm生态系统。只需在npmjs.com上注册并上传软件包即可开始审核。服务器可能不安全,因此黑客可以更改软件包。由于它们没有签名,因此无法检测更改。 - try-catch-finally