深入探究 Electron Web API 权限安全风险与防护

本文详细分析了 Electron 框架中 Web API 权限管理的安全风险,包括摄像头、麦克风、文件系统等敏感权限的默认授权机制,并与 Chrome 浏览器的安全策略进行对比,提供了具体的安全加固建议和代码示例。

深入探究 Electron Web API 权限

2022 年 9 月 27 日 - 作者:Robert Dick

引言

当 Chrome 用户打开一个请求权限的网站时,Chrome 会在左上角显示一个大型提示框。该提示会一直可见,直到用户与之交互、重新加载页面或导航离开。权限提示包含“阻止”和“允许”按钮,以及关闭选项。此外,Chrome 98 仅在权限“通过用户与网站本身的交互手势触发”时才会显示完整提示。这些预防措施是防止恶意网站使用可能影响用户隐私或安全的 API 的唯一手段。

既然 Chrome 实现了这个弹窗,Electron 如何处理权限?根据 Electron 的文档:

“在 Electron 中,权限 API 基于 Chromium 并实现了相同类型的权限。默认情况下,除非开发者手动配置了自定义处理程序,否则 Electron 会自动批准所有权限请求。虽然这是一个可靠的默认设置,但注重安全性的开发者可能希望采取完全相反的做法。”

如果 Electron 应用程序的渲染器进程通过不安全导航(例如,开放重定向、点击链接)或跨站脚本(XSS)被攻陷,这种自动批准可能导致严重的安全和隐私后果。我们决定调查 Electron 如何实现各种权限检查,以比较 Electron 与 Chrome 的行为,并确定受感染的渲染器进程可能如何滥用 Web API。

摄像头、麦克风和屏幕录制权限

当默认批准时,摄像头、麦克风和屏幕录制功能对用户构成严重风险。如果没有实现权限处理程序,Electron 应用程序的渲染器进程将可以访问用户的摄像头和麦克风。但是,屏幕录制要求 Electron 应用程序在主进程中通过 desktopCapturer 配置源。这为渲染器进程的利用留下了很小的空间,除非应用程序本身需要录制用户的屏幕。

Electron 将这三个功能归为一个权限:“media”。在 Chrome 中,这些权限是分开的。Electron 缺乏这三者之间的分离是有问题的,因为可能存在应用程序仅需要麦克风的情况,但还必须被授予录制视频的权限。默认情况下,应用程序无法在不拒绝音频访问的情况下拒绝视频访问。对于那些好奇的读者,现代 Electron 应用程序看似分别处理麦克风和视频权限,实际上只是在 UI 中跟踪和尊重用户选择。攻击者通过受感染的渲染器仍然可以访问任何媒体。

即使未授予权限,也可能枚举媒体设备。然而,在 Chrome 中,源只能看到其有权使用的设备。API navigator.mediaDevices.enumerateDevices() 将返回用户的所有媒体设备,这可用于对用户的设备进行指纹识别。例如,我们可以看到“Default - MacBook Pro Microphone (Built-in)”的标签,尽管有拒绝所有权限的处理程序。

要拒绝访问所有媒体设备(但不阻止枚举设备),必须在主进程中实现一个权限处理程序,拒绝“media”权限的请求。

文件系统访问 API

文件系统访问 API 通常允许读取和写入本地文件。在 Electron 中,读取文件已实现,但写入文件未实现,并且写入文件的权限始终被拒绝。然而,当用户选择文件或目录时,读取文件的访问权限总是被授予。在 Chrome 中,当用户选择文件或目录时,Chrome 会通知您,您正在授予对该特定文件或目录的访问权限,直到该站点的所有标签页关闭。此外,Chrome 阻止访问被认为过于敏感而无法向站点披露的目录或文件。这些都是 API 标准(由 WICG 讨论)中提到的考虑因素。

“用户代理应尝试确保用户了解他们究竟授予网站访问什么” —— 在 Chrome 中通过选择文件或目录后的通知实现

“鼓励用户代理限制用户在目录选择器中选择哪些目录,甚至可能限制用户可以选择哪些文件” —— 在 Chrome 中通过阻止用户共享包含系统文件的某些目录实现

在 Electron 中,没有这样的通知或预防措施。用户可以选择其根目录或任何其他敏感目录,可能授予网站比预期更多的访问权限。不会有通知提醒用户他们将授予的访问级别。

剪贴板、通知和空闲检测 API

对于这三个 API,渲染器进程默认被授予访问权限。这意味着受感染的渲染器进程可以读取剪贴板、发送桌面通知并检测用户何时空闲。

剪贴板

访问用户的剪贴板与安全高度相关,因为某些用户会将密码或其他敏感信息复制到剪贴板。通常,Chromium 拒绝读取剪贴板的访问权限,除非它是由用户操作触发的。然而,我们发现为窗口的加载事件添加事件处理程序允许我们在没有用户交互的情况下读取剪贴板。

要拒绝访问此 API,请拒绝“clipboard-read”权限。

通知

发送桌面通知是另一个与安全相关的功能,因为桌面通知可用于提高网络钓鱼或其他社会工程尝试的成功率。

要拒绝访问此 API,请拒绝“notifications”权限。

空闲检测

空闲检测 API 的安全性较低,但其滥用仍然代表对用户隐私的侵犯。

要拒绝访问此 API,请拒绝“idle-detection”权限。

本地字体访问 API

对于此 API,渲染器进程默认被授予访问权限。此外,主进程从未收到权限请求。这意味着受感染的渲染器进程始终可以读取用户的字体。这种行为具有重大的隐私影响,因为用户的本地字体可用于指纹识别跟踪目的,甚至可能揭示用户为特定公司或组织工作。是的,我们确实在报告中使用自定义字体!

Electron 应用程序权限的安全加固

您可以采取什么措施来降低 Electron 应用程序的风险?您可以使用 ElectroNG 快速评估是否正在缓解这些问题以及当前缓解措施的有效性,这是第一个能够快速检测漏洞并识别缺失加固配置的 SAST 工具。在其众多功能中,ElectroNG 具有专门检查,旨在识别您的应用程序是否免受权限相关滥用:

安全的应用程序通常会默认拒绝所有危险 Web API 的权限。这可以通过向 Session 添加权限处理程序来实现,如下所示:

1
2
3
ses.setPermissionRequestHandler((webContents, permission, callback) => {
  return callback(false);
})

如果您的应用程序需要允许渲染器进程访问某些 Web API,您可以通过修改权限处理程序来添加例外。我们建议检查请求权限的来源是否与预期来源匹配。最佳实践是首先将权限请求处理程序设置为 null,以强制重新请求任何权限。如果没有这个,已成功使用的权限在撤销后可能仍然可用。

1
session.defaultSession.setPermissionRequestHandler(null);

结论

正如我们所讨论的,这些权限即使用于设置了最严格的 webPreferences 的 Electron 应用程序,也对用户构成重大风险。因此,安全团队和开发人员严格管理 Electron 将自动批准的权限非常重要,除非开发者手动配置了自定义处理程序。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计