Electron

安全性,本地能力和您的责任 | Security, Native Capabilities, and Your Responsibility

Security, Native Capabilities, and Your Responsibility

作为网页开发人员,我们通常享受浏览器强大的安全网络 - 与我们编写的代码相关的风险相对较小。我们的网站在沙箱中被授予有限的权力,我们相信我们的用户可以享受由大型工程师团队构建的浏览器,能够快速响应新发现的安全威胁。

在使用Electron时,了解Electron不是Web浏览器很重要。它允许您使用熟悉的Web技术来构建功能丰富的桌面应用程序,但您的代码具有更强大的功能。JavaScript可以访问文件系统,用户外壳等。这使您可以构建高质量的本机应用程序,但固有的安全风险会随着授予代码的额外功能而扩大。

考虑到这一点,请注意,显示来自不受信任来源的任意内容会造成Electron无意处理的严重安全风险。实际上,最流行的电子应用程序(Atom,Slack,Visual Studio Code等)主要显示本地内容(或者没有Node集成的可信任的安全远程内容) - 如果您的应用程序通过在线来源执行代码,则您有责任确保代码不是恶意的。

报告安全问题

有关如何正确披露Electron漏洞的信息,请参阅SECURITY.md

Chromium安全问题和升级

尽管Electron努力尽快支持Chromium的新版本,但开发人员应该意识到升级是一项严肃的工作 - 涉及手动编辑数十甚至数百个文件。考虑到今天可用的资源和贡献,Electron通常不会使用最新版本的Chromium,而是落后于数天或数周。

我们认为,我们目前的Chromium组件更新系统在我们可用的资源与构建在框架之上的大多数应用程序的需求之间取得了适当的平衡。我们绝对有兴趣听到更多关于在Electron之上构建事物的人的具体用例。拉客请求和贡献支持这一努力总是非常受欢迎。

忽略上述建议

每当您从远程目标接收代码并在本地执行代码时,都会存在安全问题。例如,考虑在浏览器窗口内显示远程网站。如果攻击者以某种方式设法更改所述内容(通过直接攻击源代码或通过坐在应用程序和实际目标之间),他们将能够在用户计算机上执行本机代码。

在任何情况下,您都不应加载并执行启用了节点集成的远程代码。相反,只能使用本地文件(与应用程序一起打包)来执行节点代码。要显示远程内容,请使用webview标签并确保禁用nodeIntegration

清单

这不是bulletproof的,但至少应该尝试以下方法:

  • 只显示安全(https)内容

  • 在显示远程内容的所有渲染器中禁用节点集成(设置nodeIntegrationfalsein webPreferences

  • 在显示远程内容的所有渲染器中启用上下文隔离(设置contextIsolationtruein webPreferences

  • ses.setPermissionRequestHandler()在加载远程内容的所有会话中使用

  • 不要禁用webSecurity。禁用它将禁用同源策略。

  • 定义一个Content-Security-Policy,并使用限制性规则(即script-src 'self'

  • 覆盖和禁用eval,允许字符串作为代码执行。

  • 不要设置allowRunningInsecureContent为true。

  • 不要启用experimentalFeaturesexperimentalCanvasFeatures除非你知道你在做什么。

  • blinkFeatures除非你知道你在做什么,否则不要使用。

  • WebViews:不要添加nodeintegration属性。

  • WebViews:不要使用 disablewebsecurity

  • WebViews:不要使用 allowpopups

  • WebViews:不要使用insertCSSexecuteJavaScript使用远程CSS / JS。

  • WebViews:<webview>在使用will-attach-webview事件连接之前验证所有标签的选项和参数:

app.on('web-contents-created', (event, contents) => { contents.on('will-attach-webview', (event, webPreferences, params) => { // Strip away preload scripts if unused or verify their location is legitimate delete webPreferences.preload delete webPreferences.preloadURL // Disable node integration webPreferences.nodeIntegration = false // Verify URL being loaded if (!params.src.startsWith('https://yourapp.com/')) { event.preventDefault() } }) })

再一次,这个清单只是最大限度地降低了风险,并没有将其删除。如果你的目标是显示一个网站,浏览器将是一个更安全的选项。