nodeIntegration | Electron安全

admin 2024年4月14日19:22:40评论4 views字数 12548阅读41分49秒阅读模式

0x00 提醒

上一篇Electron 安全与你我息息相关文章非常的长,虽然提供了 PDF 版本,但还是导致很多人仅仅是点开看了一下,完读率大概 7.95% 左右,但上一篇真的是我觉得很重要的一篇,对大家了解 Electron 开发的应用程序安全有帮助,与每个人切实相关

但是上一篇文章内容太多,导致很多内容粒度比较粗,可能会给大家造成误解,因此我们打算再写一些文章,一来是将细节补充清楚,二来是再此来呼吁大家注意Electron 安全这件事,如果大家不做出反应,应用程序的开发者是不会有所行动的,这无异于在电脑中埋了一些地雷

我们的公众号已开启了留言功能,大家可以在文章下留言讨论啦~

0x01 简介

Electron 的架构以及开发等知识可以参照官网,官网有非常详细的介绍,今天我们要谈论的可能是 Electron 最重要的安全特性之一  —— nodeIntegration

https://www.electronjs.org/zh/docs/latest/

https://www.electronjs.org/zh/docs/latest/tutorial/security#2-%E4%B8%8D%E8%A6%81%E4%B8%BA%E8%BF%9C%E7%A8%8B%E5%86%85%E5%AE%B9%E5%90%AF%E7%94%A8-nodejs-%E9%9B%86%E6%88%90

Electron 5 版本以来,这个特性被默认设置为 false

https://releases.electronjs.org/releases/stable?version=5&page=7&limit=2

时间为 2019-04-24 (1815 days ago)

Electron 20 版本以来,除非指定 nodeIntegration: truesandbox: false ,不然渲染器会被沙盒化

那这个特性是干什么呢?

官方的解释是:

是否启用Node integration

官方在安全建议中是这样描述的

加载远程内容时,不论使用的是哪一种渲染器(BrowserWindowBrowserView 或者 webview),最重要的就是绝对不要启用 Node.js 集成。其目的是限制您授予远程内容的权限, 从而使攻击者在您的网站上执行 JavaScript 时更难伤害您的用户。

这个描述似乎在说,开启了 nodeIntegration 之后,渲染进程就可以获取到  NodeJS 的能力,这样渲染进程可以直接使用系统相关的方法,进而达到命令执行的效果

官方眼中的渲染器到底具体是什么呢?预加载脚本?渲染页面中的 JS ?是否还包括那些嵌入的页面中的 JS  ,他们都可以获取到这种能力吗?

带着这种疑问,我们开始今天的文章

这篇文章在文末也提供了 PDF 版本

  • 0x00 提醒

  • 0x01 简介

  • 0x02 搭建测试程序

    • 1. 测试项

    • 2. 配置分组

    • 3. Electron 版本管理

    • 4. Payload

    • 5. iframe 服务器

    • 6. window.open 服务器

    • 7. 关闭 CSP

  • 0x03 Electron 3.0

    • 默认配置

    • 配置 1

    • 配置 2

    • 配置 3

    • 配置 4

    • 配置 5

    • 配置 9

    • Electron 3.0 总结

  • 0x04 Electron 5.0

    • 默认配置

    • 配置 1

    • 配置 2

    • 配置 3

    • 配置 4

    • 配置 5

    • 配置 9

    • Electron 5.0 总结

  • 0x05 Electron 19.0

    • 默认配置

    • 配置 1

    • 配置 2

    • 配置 3

    • 配置 4

    • 配置 9

    • Electron 19.0 总结

  • 0x06 Electron 20.0

    • 默认配置

    • 配置 1

    • 配置 2

    • 配置 3

    • 配置 4

    • 配置 9

    • 配置 6

    • Electron 20.0 总结

  • 0x07 Electron 29.0

    • 默认配置

    • 配置 1

    • 配置 2

    • 配置 3

    • 配置 4

    • 配置 9

    • 配置 6

    • Electron 29.0 总结

  • 0x08 小结

  • 0x09 总结

  • 0x10 PDF 版本&Github

  • 往期文章

0x02 搭建测试程序

nodeIntegration | Electron安全

我们根据官方重大更改中提到的两个节点 Electron 5.0Electron 20.0 将整个时间线分成四段,取 5 个点,分别测试一下 nodeIntegration 的具体影响

1. 测试项

Electron 官方开发了 Electron Fiddle 程序,可以直接选择 Electron 版本,非常方便,但是需要系统准备对应的 NodeJS 环境,代码就使用默认的,我们在其中 "加料",我们主要从以下几个角度测试

https://www.electronjs.org/zh/fiddle

安全配置 测试点
nodeIntegration 渲染页面
contextIsolation 预加载脚本 (Preload)
sanbox iframe 内页面

2. 配置分组

按照 truefalse 进行分组

配置序号 nodeIntegration contextIsolation sanbox
1 true true true
2 true true false
3 true false true
4 true false false
5 false true true
6 false true false
7 false false true
8 false false false

3. Electron 版本管理

每个 Electron 版本对应的 NodeJS 版本如下

Electron 版本 NodeJS 版本
Electron 3.0 NodeJS 10.2.0
Electron 5.0 NodeJS 12.0.0
Electron 19.0 NodeJS 16.14.2
Electron 20.0 NodeJS 16.15.0
Electron 29.0 NodeJS 20.9.0

使用 nvm 进行多版本管理,用 Deepin Linux 进行测试

https://github.com/nvm-sh/nvm

低版本的 Nodejs 就用 Ubuntu Desktop 18.04 来进行安装,高版本的 NodejsDeepin Linux 进行安装测试

安装 Fiddle

https://www.electronjs.org/zh/fiddle

nodeIntegration | Electron安全

安装 nvm

https://github.com/nvm-sh/nvm

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

4. Payload

Deepin

require('child_process').exec('deepin-music')

Payload 是打开 Deepin 音乐程序

Windows 11

require('child_process').exec('calc')

MacOS

require('child_process').exec('open /System/Applications/Calculator.app')

5. iframe 服务器

在内网起一个 http 服务器,设置一个恶意的 html

192.168.31.215
<!DOCTYPE html>
<html>
<head>
</head>
<body>

<div>
  <h1>Hello World!</h1>
  <script>require('child_process').exec('deepin-music')</script>
</div>

</body>
</html>

nodeIntegration | Electron安全

6. window.open 服务器

192.168.31.215

iframe 中通过 window.open 打开页面进行执行

2.html

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <div>
      <h1>Hello World!</h1>
      <script>window.open("http://192.168.31.215/3.html")</script>
    </div>
  </body>
</html>

3.html

<!DOCTYPE html>
<html>
<head>
</head>
<body>
  <div>
    <h1>Hello World!</h1>
    <script>require('child_process').exec('deepin-music')</script>
  </div>
</body>
</html>

7. 关闭 CSP

为了测试 iframe ,关闭 CSP

0x03 Electron 3.0

安装 NodeJs 10.2.0

nvm install 10.2.0
nodeIntegration | Electron安全
nodeIntegration | Electron安全

这里会安装失败,可能是版本太老了,所以该用命令行进行安装

sudo npm install -g [email protected]
nodeIntegration | Electron安全
nodeIntegration | Electron安全

Fiddle 中添加我们自行安装的 Electron 3.0.0

nodeIntegration | Electron安全
nodeIntegration | Electron安全
nodeIntegration | Electron安全
nodeIntegration | Electron安全
nodeIntegration | Electron安全

点击 Run 测试是否可以正常显示

nodeIntegration | Electron安全
nodeIntegration | Electron安全

能够正常运行

按照官方手册介绍,Electron 3.0 默认安全配置为

  • nodeIntegration: true
  • contextIsolation: false
  • sandbox: false

默认配置

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

iframe直接执行失败, window.open 执行成功

小结

在默认配置中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

配置 1

nodeIntegration: true
contextIsolation: true
sandbox: true

分别尝试在 预加载脚本、渲染进程、iframe 中进行测试

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 1 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

配置 2

nodeIntegration: true
contextIsolation: true
sandbox: false

这回只需要在上一步中不能执行 NodeJS 的环境中测试

预加载脚本

肯定可以

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 2 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

配置 3

nodeIntegration: true
contextIsolation: false
sandbox: true

这回只需要在配置 1 中不能执行 NodeJS 的环境中测试

预加载脚本

肯定可以

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 3 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

配置 4

nodeIntegration: true
contextIsolation: false
sandbox: false

这回只需要在配置 1 中不能执行 NodeJS 的环境中测试

预加载脚本

肯定可以

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

iframe window.open 测试

iframe 中通过 window.open 打开页面进行执行

2.html

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <div>
      <h1>Hello World!</h1>
      <script>window.open("http://192.168.31.215/3.html")</script>
    </div>
  </body>
</html>


3.html

<!DOCTYPE html>
<html>
<head>
</head>
<body>
  <div>
    <h1>Hello World!</h1>
    <script>require('child_process').exec('deepin-music')</script>
  </div>
</body>
</html>
nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功执行,当然,我是测试过了,在前面的配置中是无法执行的

小结

在配置 4 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

配置 5

nodeIntegration: false
contextIsolation: true
sandbox: true

分别尝试在 预加载脚本、渲染进程、iframe 中进行测试

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功执行

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

小结

在配置 5 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

配置 9

nodeIntegration: false
contextIsolation: false
sandbox: false

分别尝试在 预加载脚本、渲染进程、iframe 中进行测试

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

小结

在配置 9 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

剩下就不用测试了了,可以得出结论了

Electron 3.0 总结

预加载脚本、渲染页面、iframe 测试点在以下情况可以执行 NodeJS

安全配置 预加载脚本 渲染页面 iframe
nodeIntegration 不影响 true true
contextIsolation 不影响 false false
sandbox 不影响 false false
额外条件 + window.open

在默认配置中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

0x04 Electron 5.0

Electron 5.0Linux 上无法使用 sandbox: true ,所以 sandbox: true 的部分在 Windows 上进行验证

【Windows 部分配置安装】

安装 nvm-windows

https://github.com/coreybutler/nvm-windows

安装 NodeJS 12.0.0

nvm install 12.0.0
nvm use 12.0.0
nodeIntegration | Electron安全

新建文件夹并创建 NodeJS 项目

https://www.electronjs.org/zh/docs/latest/tutorial/quick-start

npm init
nodeIntegration | Electron安全

安装 Electron 5.0

npm install --save-dev [email protected]
nodeIntegration | Electron安全

package.json 中添加启动参数

nodeIntegration | Electron安全

准备脚本,也就是 Fiddle 中的 main.jsrenderer.jsindex.htmlpreload.js

nodeIntegration | Electron安全

启动项目测试一下

npm run start
nodeIntegration | Electron安全

可以正常启动

【Linux部分配置安装】

安装 NodeJS 12.0.0

nvm install 12.0.0
nvm use 12.0.0

安装 Electron 5.0

npm install -g [email protected]
nodeIntegration | Electron安全

Electron 3.0 一样,版本较低,需要手动配置

nodeIntegration | Electron安全
nodeIntegration | Electron安全

按照官方手册介绍,Electron 5.0 默认安全配置为

  • nodeIntegration: false
  • contextIsolation: true
  • mixed sandbox: true
  • sandbox: false

5.0 的发布说明中写明了,mixed sandbox 默认启用,但是 mixed sandbox 并不等同于 sandbox,至于 sandbox 具体是什么,在官网也没有搜索到

https://www.electronjs.org/zh/blog/electron-5-0

默认配置

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在默认配置中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

配置 1

nodeIntegration: true
contextIsolation: true
sandbox: true  

分别尝试在 预加载脚本、渲染进程、iframe 中进行测试

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 1 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

配置 2

nodeIntegration: true
contextIsolation: true
sandbox: false

这回只需要在上一步中不能执行 NodeJS 的环境中测试

预加载脚本

肯定可以

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 2 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

配置 3

nodeIntegration: true
contextIsolation: false
sandbox: true

这回只需要在配置 1 中不能执行 NodeJS 的环境中测试

预加载脚本

肯定可以

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 3 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

配置 4

nodeIntegration: true
contextIsolation: false
sandbox: false

这回只需要在配置 1 中不能执行 NodeJS 的环境中测试

预加载脚本

肯定可以

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

小结

在配置 4 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

配置 5

nodeIntegration: false
contextIsolation: true
sandbox: true

分别尝试在 预加载脚本、渲染进程、iframe 中进行测试

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功执行

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 5 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

配置 9

nodeIntegration: false
contextIsolation: false
sandbox: false

分别尝试在 预加载脚本、渲染进程、iframe 中进行测试

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 9 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

剩下就不用测试了了,可以得出结论了

Electron 5.0 总结

预加载脚本、渲染页面、iframe 测试点在以下情况可以执行 NodeJS

安全配置 预加载脚本 渲染页面 iframe
nodeIntegration 不影响 true true
contextIsolation 不影响 false false
sandbox 不影响 false false
额外条件 + window.open

在默认配置中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

0x05 Electron 19.0

安装 NodeJS 16.14.2

nvm install 16.14.2
nodeIntegration | Electron安全

安装 Electron 19.0

这回直接用 Fiddle 就可以了

nodeIntegration | Electron安全
nodeIntegration | Electron安全

按照官方手册介绍,Electron 19.0 默认安全配置

  • nodeIntegration: false
  • contextIsolation: true
  • sandbox: false

默认配置

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在默认配置中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

配置 1

nodeIntegration: true
contextIsolation: true
sandbox: true  

分别尝试在 预加载脚本、渲染进程、iframe 中进行测试

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

这里可以看出,预加载脚本就只能执行受限制的 NodeJS 方法了,基本无直接危害

失败

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全

![ ](../../../../../Library/Application Support/typora-user-images/image-20240413015409087.png)

失败

小结

在配置 1 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

配置 2

nodeIntegration: true
contextIsolation: true
sandbox: false

这回只需要在上一步中不能执行 NodeJS 的环境中测试,也就是全部环境了

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 2 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

配置 3

nodeIntegration: true
contextIsolation: false
sandbox: true

这回只需要在配置 1 中不能执行 NodeJS 的环境中测试

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

直接执行失败, window.open 执行失败

小结

在配置 3 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

配置 4

nodeIntegration: true
contextIsolation: false
sandbox: false

这回只需要在配置 1 中不能执行 NodeJS 的环境中测试

预加载脚本

肯定可以

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 4 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

配置 9

nodeIntegration: false
contextIsolation: false
sandbox: false

分别尝试在 预加载脚本、渲染进程、iframe 中进行测试

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 9 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

剩下就不用测试了了,可以得出结论了

Electron 19.0 总结

预加载脚本、渲染页面、iframe 测试点在以下情况可以执行 NodeJS

安全配置 预加载脚本 渲染页面 iframe
nodeIntegration 不影响 true
contextIsolation 不影响 false
sandbox false false
额外条件

这里不着急谈绕过和覆盖,那是下一篇文章要探讨的

在默认配置中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

0x06 Electron 20.0

安装 NodeJS 16.15.0

nvm install 16.15.0
nodeIntegration | Electron安全

安装 Electron 20.0

这回直接用 Fiddle 就可以了

nodeIntegration | Electron安全

按照官方手册介绍,Electron 20.0 默认安全配置

  • nodeIntegration: false
  • contextIsolation: true
  • sandbox: true

Deepin Linux 中,Electron 20这个版本开发者工具里面的 console 打不开,一点就闪退,可能是 bug ,所以用 MacOS 进行代替

默认配置

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在默认配置中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

配置 1

nodeIntegration: true
contextIsolation: true
sandbox: true  

分别尝试在 预加载脚本、渲染进程、iframe 中进行测试

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

这里可以看出,预加载脚本就只能执行受限制的 NodeJS 方法了,基本无直接危害

失败

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 1 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

配置 2

nodeIntegration: true
contextIsolation: true
sandbox: false

这回只需要在上一步中不能执行 NodeJS 的环境中测试,也就是全部环境了

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功执行

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 2 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

配置 3

nodeIntegration: true
contextIsolation: false
sandbox: true

这回只需要在配置 1 中不能执行 NodeJS 的环境中测试

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

直接执行失败, window.open 执行失败

小结

在配置 3 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

配置 4

nodeIntegration: true
contextIsolation: false
sandbox: false

这回只需要在配置 1 中不能执行 NodeJS 的环境中测试

预加载脚本

肯定可以

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 4 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

配置 9

nodeIntegration: false
contextIsolation: false
sandbox: false

分别尝试在 预加载脚本、渲染进程、iframe 中进行测试

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 9 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

配置 6

nodeIntegration: false
contextIsolation: true
sandbox: false

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

剩下就不用测试了了,可以得出结论了

Electron 20.0 总结

预加载脚本、渲染页面、iframe 测试点在以下情况可以执行 NodeJS

安全配置 预加载脚本 渲染页面 iframe
nodeIntegration 不影响 true
contextIsolation 不影响 false
sandbox false false
额外条件

这里不着急谈绕过和覆盖,那是下一篇文章要探讨的

在默认配置中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

0x07 Electron 29.0

安装 NodeJS 20.9.0

nvm install 20.9.0
nodeIntegration | Electron安全

安装 Electron 29.0

这回直接用 Fiddle 就可以了

nodeIntegration | Electron安全

按照官方手册介绍,Electron 29.0 默认安全配置应该和 20.0 一样

  • nodeIntegration: false
  • contextIsolation: true
  • sandbox: true

默认配置

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在默认配置中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

配置 1

nodeIntegration: true
contextIsolation: true
sandbox: true  

分别尝试在 预加载脚本、渲染进程、iframe 中进行测试

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 1 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

配置 2

nodeIntegration: true
contextIsolation: true
sandbox: false

这回只需要在上一步中不能执行 NodeJS 的环境中测试,也就是全部环境了

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 2 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

配置 3

nodeIntegration: true
contextIsolation: false
sandbox: true

这回只需要在配置 1 中不能执行 NodeJS 的环境中测试

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

直接执行失败, window.open 执行失败

小结

在配置 3 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

配置 4

nodeIntegration: true
contextIsolation: false
sandbox: false

这回只需要在配置 1 中不能执行 NodeJS 的环境中测试

预加载脚本

肯定可以

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 4 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

配置 9

nodeIntegration: false
contextIsolation: false
sandbox: false

分别尝试在 预加载脚本、渲染进程、iframe 中进行测试

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

小结

在配置 9 中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe

配置 6

nodeIntegration: false
contextIsolation: true
sandbox: false

预加载脚本

nodeIntegration | Electron安全
nodeIntegration | Electron安全

成功

渲染进程

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败,而且因为 bug 还不允许打开 console

iframe

nodeIntegration | Electron安全
nodeIntegration | Electron安全

失败

剩下就不用测试了了,可以得出结论了

Electron 29.0 总结

预加载脚本、渲染页面、iframe 测试点在以下情况可以执行 NodeJS

安全配置 预加载脚本 渲染页面 iframe
nodeIntegration 不影响 true
contextIsolation 不影响 false
sandbox false false
额外条件

这里不着急谈绕过和覆盖,那是下一篇文章要探讨的

在默认配置中

测试点 是/否可以执行 NodeJS
预加载脚本
渲染页面
iframe
iframe + window.open

0x08 小结

将以上几个版本的总结贴到一起,如下

nodeIntegration | Electron安全

相同的配置在不同版本下表现的结果并不完全相同,在 5.019.0 之间的重大更改中,并未提及 sandbox 对页面影响的变化,但实际上至少在 19.0 版本开始,预加载脚本想要 NodeJS 能力必须设置 sandbox (这里的 sandbox 是指主进程创建窗口时候的 sandbox),那到底是从哪个版本开始的呢?

所以我们需要再次测试了,但这里就不把过程中展示出来了

Electron 6.0.0 开始 sandbox: true 时, Preload 脚本的 NodeJS 环境为受限环境

再此之前即使设置了 sandbox: true预加载脚本还是可以加载并使用require('child_process') 这种模块

经过测试 iframe + window.open 的问题在 Electron 14.0.0 中被修复

0x09 总结

从上面的对比结果可以看出, nodeIntegration 的作用确实是主要在于渲染进程是否具备执行 NodeJS 的能力,只有当 nodeIntegration 被设置为 true 时,渲染进程(这里不含 preload)  和 iframe 才有可能获取到执行 NodeJS 的能力,但也同时配合关闭上下文隔离和沙箱

如果采用默认配置,则三个配置项的时间线如下

nodeIntegration | Electron安全

如果从攻击测试视角查看默认配置项时间线如下

nodeIntegration | Electron安全

当然,这个是从这篇文章出发的,这篇文章主要讨论 nodeIntegration 这个参数,其他攻击手法及时间线没有放入图中

这里再次呼吁,对于 Electron 程序,我们至少可以按照上一篇文章 Electron安全与你我息息相关 中介绍的普通用户可操作的检查方式对使用的应用程序的安全性进行检查,进而决定使用该程序时的注意事项以及要不要继续使用,当然更好的是向开发者提出建议,采用更安全的开发方式

0x10 PDF 版本&Github

PDF 版本下载地址

https://pan.baidu.com/s/164fZ7KXzD_jktW_UG3oA2w?pwd=zcj9

我们将 Electron 安全相关的内容建立了一个 Github 项目,地址如下

https://github.com/Just-Hack-For-Fun/Electron-Security

往期文章

nodeIntegration | Electron安全

有态度,不苟同

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年4月14日19:22:40
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   nodeIntegration | Electron安全https://cn-sec.com/archives/2655796.html

发表评论

匿名网友 填写信息