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比較適合擁抱開源生態的開發者,不適合個人及企業對保護原始碼,保護自身的專利技術及智慧財產權的應用開發。