长亭百川云 - 文章详情

跳转与导航 | Electron 安全

NOP Team

86

2024-07-13

0x01 简介

导航我们都知道,高德地图对吧,我们搜索一个地点,它告诉我们如何到达。对于网站来说,导航是帮助用户到达用户想去的地方(网址)

Electron 中也是一样,凡是离开当前地址的操作都可以算作是跳转和导航,最常见的是点击了某个链接,之后我们进入到链接中,点击了某个功能,进入到该功能模块中

对于应用程序来说,通常不需要在页面中渲染第三方的网页,尤其是在 Electron 中,加载第三方页面可能会导致用户被远程命令执行,因此官方推荐禁用或限制网页跳转

参考文章

https://www.electronjs.org/zh/docs/latest/tutorial/security#13-%E7%A6%81%E7%94%A8%E6%88%96%E9%99%90%E5%88%B6%E7%BD%91%E9%A1%B5%E8%B7%B3%E8%BD%AC

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

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


  • 0x01 简介

  • 0x02 效果展示

  • 0x03 官方安全建议

  • 0x04 哪些行为会导致网页跳转

  • 1. a 标签

  • 2. 表单提交

  • 3. meta 标签自动刷新

  • 4. iframe 加载

  • 5. window.location

  • 6. window.history

  • 7. window.open

  • 8. window.top

  • 0x05 漏洞案例

  • 0x06 总结

  • 0x07 PDF 版 & Github

  • 往期文章


0x02 效果展示

点击链接后

0x03 官方安全建议

官方建议是禁用或限制网页跳转,所谓的限制也就是说选择性地网页跳转,例如允许跳转到自己以及子域名等可控范围内的内容,官方给出代码如下

`const { URL } = require('url')   const { app } = require('electron')      app.on('web-contents-created', (event, contents) => {     contents.on('will-navigate', (event, navigationUrl) => {       const parsedUrl = new URL(navigationUrl)          if (parsedUrl.origin !== 'https://example.com') {         event.preventDefault()       }     })   })   `

官方还专门强调,建议使用Node的解析器来处理URL, 简单的字符串比较有时会出错

0x04 哪些行为会导致网页跳转

既然有了防御代码,我们便可以测试一下,到底哪些行为会进行网页跳转

1. a 标签

点击 a 标签后,成功输出 URL 对象,其中完整内容为

`URL {     href: 'https://www.baidu.com/robots.txt',     origin: 'https://www.baidu.com',     protocol: 'https:',     username: '',     password: '',     host: 'www.baidu.com',     hostname: 'www.baidu.com',     port: '',     pathname: '/robots.txt',     search: '',     searchParams: URLSearchParams {},     hash: ''   }   `

其中 origin 就是我们所谓的同源策略里的源,它包含协议、主机名、端口号

所以官方的防御代码就是验证是不是与 https://example.com 同源的,非同源则直接组织

2. 表单提交

`<form action="https://example.com/submit" method="POST">     <!-- 表单内容 -->     <input type="text" name="username">     <button type="submit">提交</button>   </form>   `

上一节新窗口创建的案例,当然这里 target 设置什么无所谓,我们直接去掉了,关键是 action 属性,这个属性的值造成跳转

出发了跳转和导航事件

3. meta 标签自动刷新

`<meta http-equiv="refresh" content="5;url=https://example.com">   `

5 秒后

成功触发监听

4. iframe 加载

点击按钮

创建一个 iframe 并没有引起主进程的跳转和导航事件,我们修改代码,测试一下按按钮修改 iframesrc 属性

点击按钮

看来 iframesrc 修改不会触发主进程的跳转与导航事件

iframe 加载的内容中通过 window.top.location 修改顶层窗口的 URL

5 秒后

触发导航事件

5. window.location

Window.location 只读属性返回一个 Location 对象,其中包含有关文档当前位置的信息

尽管 Window.location 是一个只读 Location 对象,你仍然可以将字符串赋值给它。这意味着可以在大多数情况下像字符串一样处理 location——location = 'http://www.example.com'——与 location.href = 'http://www.example.com' 等价。

在上一篇文章中,我们介绍了通过 window.open().location 绕过安全限制的手法,其中 location 或者说 location.href 的值就是要导航去的位置

1) location.href

返回当前页面的完整URL字符串,也可以用来设置新的URL以导航到其他页面

`window.location.href = "https://www.baidu.com/"   `

5秒后

触发导航事件

2) location.assign

导航到一个新页面

`window.location.assign("https://www.mozilla.org");   `

5秒后

触发导航事件

3) location.reload

重新加载当前页面

`window.location.reload();   `

5秒后

触发导航事件

4) location.replace

替换当前页面的 URL

`window.location.replace('https://example.com')   `

5秒后

触发导航事件

5) location.search

在 url 后面加上搜索字符串

`window.location.search = "test"   `

5 秒后

6) 其他属性

属性较多,基本上都是 URL 的一部分,如果修改也会导航事件

  • href: 返回当前页面的完整URL字符串,也可以用来设置新的URL以导航到其他页面。

  • protocol: 返回当前URL的协议部分,例如 http:https:

  • host: 返回当前URL的主机名(域名+端口),例如 example.com:8080

  • hostname: 返回当前URL的主机名(不包括端口),例如 example.com

  • port: 返回当前URL的端口号,如果省略则默认端口不会显示

  • pathname: 返回当前URL的路径部分,从根目录开始,例如 /path/to/page.html

  • search: 返回URL的查询字符串部分,从问号 ? 开始,例如 ?key=value&anotherKey=anotherValue

  • hash: 返回URL的哈希片段标识符(锚点),从井号 "#" 开始,例如 #section1

  • origin: 返回URL的起源部分,由协议、主机名和端口组成,例如 http://example.com:80

6. window.history

历史记录属性可以通过其以下几个方法进行导航

  • back(): 导航到历史记录中的上一个页面。

  • forward(): 导航到历史记录中的下一个页面。

  • go(delta): 依据delta参数向前或向后导航。正值表示向前,负值表示向后,0通常不会产生导航效果但可能刷新页面。

这就相当于浏览器的前后按钮了

7. window.open

这部分上一篇文章新窗口创建的部分已经介绍了,会触发导航事件

8. window.top

window.top 是一个JavaScript对象属性,它引用了当前窗口或框架的最顶层窗口(即最高层级的浏览器窗口)

对于没有上层窗口的渲染进程, window === window.top,所以修改  window.top.location 就可以修改当前页面的 url

对于 iframe 等子窗口,使用 window.top.location 可以修改顶层窗口的 URL

0x05 漏洞案例

Masato Kinugawa 曾经在 Discord RCE 的过程中利用了一个导航的漏洞 —— CVE-2020-15174

iframe 中,如果设置 top.location 的地址和 iframe的地址不同源,则不会触发 will-navigate 事件,即导航事件,这显然是一个 bug

https://mksben.l0.cm/2020/10/discord-desktop-rce.html

0x06 总结

网页跳转和导航的触发方法很多,但最终效果几乎都是一致的,就是在当前窗口或新窗口加载页面,在较新的版本中, will-navigate 能够有效地监听和阻断导航行为,开发者可以根据实际情况,考虑禁用或者限制导航行为

0x07 PDF 版 & Github

PDF

https://pan.baidu.com/s/1whO3bFMGfzkzyDWW64TpBw?pwd=kc4x

Github

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

往期文章

有态度,不苟同

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2