微信小程式應用安全分析及設計

MIASDZ 發表於 2021-10-13

針對微信關於小程式安全設計的分析

針對微信小程式開發配置及部分配置機制分析微信小程式安全設計:

  • AppSecret

管理員生成AppSecret,在與微信後臺互動過程中部分介面使用,如 auth.code2Session 獲取會話金鑰session_key

安全分析

AppSecret維護必須為小程式管理員維護,預設微信側管理安全

❗ AppSecret在生成後需要後臺應用儲存維護,存在洩漏風險,AppSecret後臺留存安全性需後臺應用考慮。❗

Tips: AppSecret的儲存需作為後臺應用安全設計的考慮項。

  • session_key

通過小程式獲取客戶敏感資訊時需使用會話金鑰對資料進行解密,詳見 微信開放平臺

安全分析

  • session_key獲取需後臺獲取,依賴於AppSecret、小程式wx.login操作
  • 小程式元件獲取敏感資訊需獲取客戶明示同意,且獲取資訊為加密資訊,加密資訊解密需後臺通過session_key解密,session_key獲取依賴AppSecret

✊ 敏感資訊獲取涉及wx.login、加密資料、AppSecret、session_key、客戶明示同意,環環相扣。

  • 伺服器域名

新增伺服器域名白名單,必須通過ICP備案且為HTTPS,設定後小程式可與該域名進行資訊互動

Tips: 小程式image src不受伺服器白名單限制。

安全分析

  • 即使小程式內採用不安全的JS元件(如通過NPM匯入開源元件)也可控制請求鏈路限制資訊外洩,將不安全限制在小程式內
  • 常規WEB不安全元件,獲取頁面敏感資訊後通過構造script、image等標籤發起網路請求,傳輸非法資料,微信小程式通過域名白名單機制,結合小程式不支援通過JS動態WXML構造image等標籤,即使元件獲取到資訊通過網路請求向外推送
  • 強制HTTPS確認通訊通道安全

✊ 通過白名單配置從傳輸通道控制資訊外傳風險。

Tips: 未來小程式是否支援類似於JS操作DOM方式通過JS動態修改WXML不可預知,若支援可能會引入其他的安全設計。

❗ HTTPS不安全網路下仍可被抓包檢視,介面許可權控制、敏感資料保護等仍需通過應用安全設計控制。

  • 版本管理

版本提交可設定提交版本IP白名單,限制訪問策略

安全分析

通過該機制防止APPID丟失時惡意修改程式碼上傳

  • 開發安全

提供官方微信開發者工具,保證開發工具安全

通過以上提到的開發配置及小程式機制結合分析,微信針對小程式準備了前端應用基礎環境的安全保障,小程式開發者主要需要關注應用安全設計,如介面許可權控制、敏感資料保護等,接下來需要考慮如何防範小程式基礎環境外的安全保護。

微信小程式應用安全考慮點


針對以上分析,在小程式基礎環境安全體系內,首先需要開發人員關注點包括兩部分:

1、不安全網路HTTPS抓包,交易敏感資訊明文傳輸

HTTPS抓包分析

HTTPS抓包主要通過代理軟體欺騙客戶端隱藏真實服務端、偽造客戶端訪問後臺服務方式實現HTTPS報文抓取,如BurpSuite Proxy,通過代理模擬服務端證書抓包

在HTTPS抓包下,服務端被偽造,暴露交易明文,故需通過合理的安全設計防範被抓包後的敏感資訊洩露,個人考慮可以參考HTTPS握手機制,模擬敏感資訊會話金鑰交換,保護交易報文敏感資訊

  • 敏感資料傳輸設計

首先可瞭解一下HTTPS握手機制 HTTPS加密(握手)過程

接下來對小程式敏感資料傳輸進行討論:

參考HTTPS握手過程,計劃採取同樣方式完成敏感資訊會話金鑰交換

  • 基礎
  1. 小程式內建RSA公鑰,服務端留存RSA私鑰
  2. 小程式內建RSA加密演算法、AES加解密演算法、AES隨機金鑰生成演算法、BASE64演算法、SHA256演算法
  • 會話金鑰交換
  1. AES隨機金鑰生成演算法生成會話金鑰,小程式保管會話金鑰
  2. RSA演算法通過內建RSA公鑰加密會話金鑰,用於會話金鑰明文傳輸
  3. wx.login獲取loginCode作為金鑰交換時的簽名驗證資訊部分原文
  4. 對 loginCode+會話金鑰 SHA256 HASH演算法計算會話金鑰交換握手摘要資訊,用於後臺驗證金鑰傳輸是否安全
  5. 拼接會話金鑰交換握手資訊,格式為 loginCode|sha256(loginCode+會話金鑰)
  6. 採用會話金鑰加密握手資訊,格式為 aes(握手資訊)
  7. 組裝會話金鑰交換報文,與後臺通訊互動進行金鑰交換,格式為:
    {"client_hello":"握手資訊", "secret":"rsa加密完的會話金鑰"}
  8. 後臺接受報文,解析報文,並驗證會話金鑰交換是否有效,驗證方式如下:

a. 後臺應用內建RSA私鑰解密獲取會話金鑰明文

b. 通過會話金鑰解密握手資訊獲取握手明文

c. 對解密完成的明文進行校驗簽名資訊是否正確,獲取明文竄loginCode及會話金鑰通過sha256計算簽名資訊,判斷是否與客戶端上送一致

d. 一致情況下對loginCode與微信服務端進行轉換,呼叫服務端API auth.code2Session 介面校驗loginCode是否有效

e. 會話金鑰校驗成功,後臺生成會話標識,用於後續敏感資訊傳輸時標識會話資訊

  • 安全介面設計
  1. 通過上述會話金鑰交換機制,完成了安全介面的基礎保障
  2. 在具備會話金鑰後,設計安全介面互動保障敏感資訊,設計流程如下:

a. 前端生成交易明文 json_data

b. 組織安全介面報文,包含要素:

  • 會話標識 s_session_key 來源為金鑰交換成功後服務端響應給客戶端的會話標識
  • 交易時間戳 s_time_stamp
  • 交易資料密文 s_data 來源為 aes(json_data) aes加密金鑰為會話金鑰
  • 交易報文摘要 s_mac 來源為 sha256(會話金鑰+json_data+s_time_stamp)

c. 後臺報文解密及驗證,驗證流程如下:

根據s_session_key獲取會話金鑰 --> 解密s_data獲取交易明文 --> 服務端計算 s_mac_server (獲取服務段留存會話金鑰及報文時間戳,按照前端演算法及明文拼接方式一致計算) --> 比對計算結果

  • 設計分析

通過敏感資訊會話金鑰機制,可以保護交易敏感資料不被洩露,分析如下:

  1. 內建RSA公鑰,客戶端僅包含RSA公鑰,在會話金鑰交換過程成只有服務端留存有RSA私鑰,故即使抓包,會話金鑰也無法被擷取
  2. 採用微信loginCode作為會話金鑰交換時的驗證因子,這樣後臺會話金鑰交換成功時通過loginCode與微信後臺進行介面互動,
    確保會話互動時是通過小程式官方生成的會話,通過微信介面獲取到OpenId留存會話,用於後續會話許可權控制使用
  3. s_session_key會話標識後臺未採用隨機演算法生成,通過 sha256(UUID+會話金鑰) 保證不可預知

2、安全引數保護

針對以上內容,在應用程式中存在一個風險點為應用程式敏感配置洩漏,故需針對敏感配置進行保護

敏感配置包括:AppSecret、RSA私鑰 等其他需保護的配置資訊

方式1: 對配置檔案進行加密保護,防止直接洩漏,但是在使用過程中仍需應用程式解密。

方式2: 採用Vault或類似方案儲存敏感引數,僅瞭解可通過該方式實現,具體實現自行學習。

針對以上設計,已開發程式Demo上傳至Gitee

小程式端

後臺

通用WEB安全設計

以上安全設計僅對基礎環境、通訊鏈路、通訊報文進行安全防護,針對WEB應用通用安全設計,需再行擴充套件。

許可權控制:

  • 身份標識與資料範圍繫結,限制運算元據範圍
  • 身份標識不可信任客戶端,由服務端維護
  • 操作中鑑定每個身份欄位域與當前身份一致

客戶端不可信:

  • 一切客戶端請求源資料不可信任,資料格式不可信任,資料內容不可信任

防重放:

  • 對交易進行資料標記,同標記控制交易重放

注入攻擊:

  • SQL隱碼攻擊,Mybatis框架#{}引數可以防範
  • XSS注入:任意客戶端上送資訊需進行轉碼儲存及展示

Tips: 常見防護原則包括:最小授權、客戶端不可信。

推薦讀《白帽子講web安全》

應用安全審計簡介

有安全設計,才有安全審計

審計需準確每一筆請求記錄操作時間、操作人、行為、運算元據。

總結

web應用安全涉及方方面面,包括網路安全、應用安全、系統安全等,開發人員作為應用開發專業人員,需關注應用安全,具備基本的安全底線。

各項安全面需緊密結合,才可構造出一個安全的應用環境,比如網路裝置再安全,應用層開發一個簡單的SQL查詢功能,查全庫資料,那整個應用環境也是不安全的。

Tips: 作為應用開發人員,安全底線不可失,研究防範,不可研究破壞。