Electron框架應用的安全測試
0.Electron相關簡介
electron.js是一個運行時框架,它在設計之初就結合了當今最好的Web技術,核心是使用HTML、CSS、JavaScript構建跨平台的桌面應用。
作為一個跨平台的“集成框架”,它能輕松和多平台兼容。而所謂的“集成框架”也就是它將“Chromium”和“Node.js”很好的集成,並明確分工。
Electron負責硬件部分,“Chromium”和“Node.js”負責界面與邏輯,共同構成了成本低廉卻高效的解決方案。
比如流行的VS Code,WhatsApp,WordPress等應用都是使用了electron框架來構建跨平台開發
特點如下:
1.擺脫了不同瀏覽器之間的差異和版本的限制
2.基於Node.js,有活躍的貢獻者社區管理和第三方豐富的包支持
3.可以開發跨平台的桌面應用。只需要寫一份代碼,可以構建出三個平台的應用程序
a.優勢
1.擺脫瀏覽器的沙盒機制,可以訪問操作系統層面的東西。
2.跨平台,前端人員能在不學習其他語言的情況下,快速構建跨平台,帶來統一的用戶體驗
b.劣勢
1.打包的APP太大,簡單的應用多大幾十兆
2.引入Node.js的API具備接觸系統底層的能力,控制不當易引發安全風險,直接從對瀏覽器的影響提升為對系統的影響。
1.與傳統Web開發的區別與聯系
回顧以前的web開發,無論是HTML、CSS還是Java,都是運行在瀏覽器沙盒中的,無法越過瀏覽器的權限訪問系統本身的資源,代碼的能力被限制在了瀏覽器中。瀏覽器之所以這么做,為了安全的考慮。設想一下,使用瀏覽器的時候,會打開各樣不同的網站,如果代碼有能力訪問並操作本地操作系統的資源,那將是可怕的事情。
但開發桌面應用程序,如果無法訪問到本地的資源肯定是不行的。
而使用Electron架構的應用程序分成三個基礎模塊:主進程、渲染進程、進程間通信;
Electron將nodejs引入並作為主進程,可以訪問和操作本地資源,使用原本在瀏覽器中不提供的高級API。同時主進程負責管理整個應用程序的生命周期以及所有渲染進程的創建和銷毀。 在主進程中運行的腳本通過創建web頁面來展示用戶界面。它內置了完整的Node.js API,主要用於打開對話框以及創建渲染進程。此外,主進程還負責處理與其他操作系統交互、啟動和退出應用程序。
渲染進程是應用程序中的瀏覽器窗口。與主進程不同,Electron可以有許多渲染進程,且每個進程都是獨立的。由於 Electron 使用了 Chromium 來展示 web 頁面,所以 Chromium 的多進程架構也被使用到。 每個Electron 中的 web 頁面運行在它自己的渲染進程中。正是因為每個渲染進程都是獨立的,因此一個崩潰不會影響另外一個,這些要歸功於Chromium的多進程架構。
2.對electron解包的一般思路
在Electron項目開發
中,resource\
目錄下的代碼文件默認是明文可見的,如果沒有對項目封裝打包,就可以進行白盒審計,發現更多的問題,而如果只是使用npm執行asar對app.asar文件(resources目錄里)合並歸檔,則會很容易被解包。而對Electron源碼保護方案討論由來已久。官方並沒有打算提供解決方案。作者們認為,無論用什么形式去加密打包文件,密鑰總歸是需要放在包里。
因為asar只是對源碼的合並歸檔,並不提供加密之類的操作。 通過asar e
的命令,可以很簡單地進行解壓和得到源碼。
//1.安裝npm
//2.全局安裝 asar
npm install asar -g
//3.解包
用asar命令解包:asar e app.asar app
3.DOM-Based XSS--->RCE
-
由於electron框架開發出的應用,不只是一個瀏覽器。在Web瀏覽器中,基於安全策略考慮,web頁面通常是在一個沙盒環境中運行的,不被允許去接觸原生的資源。
然而在Electron中,允許頁面(渲染進程)調用Node.js的API,原生具備操控系統底層的能力,所以頁面可以與操作系統底層進行交互,如執行系統命令,那么DOM Based-XSS在electron就會提升為RCE,直接從對瀏覽器的影響提升為對系統的影響。
Electron是基於Chromium的內容模塊實現的,但是從本質上來說它就不是一個瀏覽器。它可以給開發人員提供非常強大的功能,而且Electron的靈活性也可以有助於構建復雜的桌面應用程序。
所以,實際上Electron整合了Node.js,所以JavaScript可以直接訪問操作系統並完全利用原生的桌面機制。
如:假設在使用electron開發的應用中發現某處DOM based XSS,那么直接就可以提升為RCE,如下
//要利用electron的xss,只需要引入nodejs自帶的命令執行模塊child_process即可
//Electron框架,Dom XSS->RCE,比如彈計算器
<img src="" onerror="require('child_process').exec('calc.exe')">
<img src=1 onerror=require('child_process').exec('calc.exe')>
<img/src="1"/onerror=eval(`require("child_process").exec("calc.exe");`);>
<img src=# onerror="require('child_process').exec('calc.exe',null);">
<img src=# onerror="require('electron').shell.openExternal('file:C:/Windows/System32/calc.exe')">
5.漏洞原理
應用開發使用了Electron框架,且nodeIntegration默認值為True,說明開啟了Node.js擴展,那就能夠調用node.js模塊從XSS到RCE, 只要不進行嚴格的過濾,就會造成rce
<img src=1 onerror="require('child_process').exec('calc.exe')">
注意:
Electron中使用了一個標記nodeIntegration用來控制頁面對node的API的訪問,只有nodeIntegration為true的時候,才可以使用如require,process這樣的node API去訪問系統底層資源。
5.修復方案
1. 使用 DOMPurify 過濾 XSS Payload,或者 React JSX;
2. 謹慎開啟nodeIntegration參數,如果開啟一定要對用戶可控輸入點做好充分的過濾,如特殊字符實體編碼。
可參考:https://www.electronjs.org/docs/latest/tutorial/security#2-do-not-enable-nodejs-integration-for-remote-content
3.可使用webpack類似的前端構建工具,對項目代碼進行加密混淆
為了安全性,官方將 electron@v12.0.0 的 contextIsolation 的默認值改了。所以今后要在渲染進程里調用 require 的話,還需要加上 contextIsolation: false 。
6.總結
防御Electron開發程序的逆向,從目前看方案比較有限,混淆后效果也不佳,和傳統的二進制逆向相比,逆向難度不會太大。所以,electron比較適合擁抱開源生態的開發者,不適合個人及企業對保護源代碼,保護自身的專利技術及知識產權的應用開發。