一周多前,我在Atom论坛(下面的链接)上问了这个问题,但没有得到回应,所以我把它转发到这里,希望有人能深入了解我的问题。
最近,我开始了一个开源项目,它使用Electron作为前端。这个项目有两个要求:它必须是跨平台的,并且必须有一个嵌入式的web浏览器(它应该能够像典型的浏览器一样浏览web和呈现内容)。考虑到Electron已经在我的应用程序中占据了相当大的份额,尝试在其旁边使用另一个嵌入式web框架似乎是个坏主意。因此,为了简化我的项目并保留在Electron之上构建的UI,我正在考虑将Electron本身用作web浏览器。这就是我遇到的问题。
在Electron文件的安全页面中,明确指出,
重要的是要理解…Electron不是一个网络浏览器
与典型的web应用程序不同,Electron(或者更确切地说是运行在其上的代码)具有与用户操作系统交互的独特能力。页面继续写道,
显示来自不可信来源的任意内容会带来严重的安全风险,Electron不打算处理
在这一点上,我很想放弃使用Electron作为内置浏览器的想法,但在同一页面上,你可以找到另一个非常有趣的花絮:
要显示远程内容,请使用
<webview>
标记或BrowserView
,[并]确保禁用nodeIntegration
并启用contextIsolation
链接:https://electronjs.org/docs/tutorial/security#isolation-对于不受信任的内容
首先,关于使用网络视图,Electron自己的文档建议完全避免使用:
Electron的
webview
标签基于Chromium的webview
,后者正在经历巨大的架构变化。这会影响webviews
的稳定性,包括渲染、导航和事件路由。我们目前建议不要使用webview
标签,而是考虑其他选择,如iframe
、Electron的BrowserView
或完全避免嵌入内容的架构。
链接:https://electronjs.org/docs/api/webview-tag
我觉得我无法避免嵌入内容,所以我选择了使用BrowserView,但我发现这也不是很有动力。目前的建议是做两件事:
- 禁用
nodeIntegration
- 启用
contextIsolation
在查看了安全和最佳实践页面后,我还将附加以下步骤:
- 拒绝来自远程内容(网络摄像头、麦克风、位置等)的会话权限请求
- 在创建中捕获
webview
元素并剥夺默认权限 - 禁止创建新窗口
- 禁用远程模块
在保护外部内容方面,这是一个相当多的步骤。更不用说,最佳实践页面上散布着一些额外的警告,例如:
(在创建之前验证网络视图选项)
同样,此列表只是将风险降至最低,并没有将其删除。如果您的目标是显示网站,浏览器将是一个更安全的选择。
链接:https://electronjs.org/docs/tutorial/security#11-在创建之前验证webview选项
(禁用remote
模块时)
然而,如果您的应用程序可以运行不受信任的内容,即使您相应地对渲染器进程进行沙箱操作,远程模块也会使恶意代码很容易逃离沙箱,并通过主进程的更高权限访问系统资源。
链接:https://electronjs.org/docs/tutorial/security#15-禁用远程模块
更不用说,当导航到BrowserView
页面时,整个类都被列为实验类。
这还不算Electron增加的攻击面,比如去年webview
组件中的一个漏洞:CVE-2018-1000136
现在,考虑到以上所有因素,许多开发人员仍然选择使用Electron创建经常使用外部和不受控制的内容的web浏览器。
浏览器使用Electron(直接从Electron的网站链接):
- https://electronjs.org/apps/wexond
- https://electronjs.org/apps/dot
- https://electronjs.org/apps/beaker-browser
对我来说,为了方便起见,让用户接受上述安全影响似乎是不负责任的。
话虽如此,我的问题是:您能否安全地使用Electron为不受控制的内容实现网络浏览功能,以确保用户的完整性
谢谢你抽出时间。
链接到原始帖子:https://discuss.atom.io/t/security-implications-in-electron-as-a-web-browser/70653
一些不适合放在评论框中的想法:
[项目]必须具有嵌入式web浏览器
所以我认为这个项目不仅仅是一个网络浏览器。还有其他内容可能可以访问Node,但您只希望它的嵌入式web浏览器部分被适当地沙盒起来,对吧?
关于<webview>
的评论,是的,它被认为是不稳定的,Electron建议使用BrowserView
。我不认为它被标记为"实验性"这一事实一定会阻止你使用它(尤其是考虑到Electron团队正在推荐它(尽管可能是两害相权取其一))。
实验并不意味着它是不稳定的。这可能意味着Electron团队正在试验这种方法,但这种方法在未来可能会改变(在这一点上,我希望Electron能够提供一条前进的过渡道路)。尽管这是一种可能的解释,最终Electron将不得不对此发表评论。
建议。。。就是做两件事:
- 禁用nodeIntegration
- 启用上下文隔离
我还将使用从BrowserWindows
继承的sandbox
选项。BrowserView's
关于构造函数选项的文档说:
webPreferences
对象(可选)-请参阅BrowserWindow。
它告诉我BrowserView
接受与BrowserWindow
相同的选项。
你可以这样设置:
new BrowserView({ webPreferences: {
sandbox: true,
nodeIntegration: false,
contextIsolation: true,
preload: "./pathToPreloadScript.js"
}});
请在此处查看有关此方法的更多信息。预加载脚本将向您正在加载的沙盒内容公开一些Node IPC API。请注意底部的"状态"部分,上面写着:
请小心使用
sandbox
选项,因为它仍然是一个实验功能。我们仍然没有意识到将一些Electron渲染器API暴露于预加载脚本的安全影响
如果您在BrowserView
中加载的内容永远不需要与应用程序通信,那么您根本不需要预加载脚本,只需对BrowserView
进行沙盒处理即可。
在查看了安全和最佳实践页面后,我还将附加以下步骤:
- 拒绝来自远程内容(网络摄像头、麦克风、位置等)的会话权限请求
- 在创建中捕获webview元素并剥夺默认权限
- 禁止创建新窗口
- 禁用远程模块
当然,这些听起来很合理。请注意,如果嵌入式浏览器需要能够打开新窗口(通过window.open
或<a target="_blank" />
),则必须允许弹出窗口。
在保护外部内容方面,这是一个相当多的步骤。
当然,但你主要关心的是应用程序的安全性,还是需要做多少工作才能确保安全?浏览器开发人员需要考虑类似的事情,以确保网页无法访问操作系统。这只是游戏的一部分。
同样,此列表只是将风险降至最低,并没有将其删除。如果您的目标是显示网站,浏览器将是一个更安全的选择。
这只是说,如果你想要做的只是显示一个网站,那么只需使用浏览器,因为这就是他们的目的。
如果你需要做其他事情,那么你就不能使用浏览器,所以你必须制作自己的应用程序,确保它合理地安全。
我认为,如果你遵循安全文件中的建议,并跟上新的Electron版本,那么你就是在尽你所能。
至于这是否足够好,我不能说。这取决于你正在发展什么以及你试图防范什么。
然而,我的想法无法取代Electron团队中那些更专业的意见。这个问题当然需要他们的一些指导。