跳至主要內容

安全性誤判

簡介

#

我們偶爾會收到由針對其他類型應用程式(例如,使用 Java 或 C++ 編寫的應用程式)建置的工具所產生,關於 Dart 和 Flutter 應用程式中安全性漏洞的錯誤報告。本文檔提供關於我們認為不正確的報告資訊,並解釋為何這些疑慮是錯誤的。

常見疑慮

#

共享物件應使用強化函數

#

共享物件沒有任何強化函數。強化函數針對 glibc 的常見不安全函數(如 strcpygets 等)提供緩衝區溢位檢查。請使用編譯器選項 -D_FORTIFY_SOURCE=2 來強化函數。

當這指的是編譯過的 Dart 程式碼(例如 Flutter 應用程式中的 libapp.so 檔案)時,此建議是誤導的,因為 Dart 程式碼不會直接調用 libc 函數;所有 Dart 程式碼都透過 Dart 標準函式庫進行。

(一般來說,MobSF 在此處會出現錯誤的肯定結果,因為它會檢查是否有任何使用帶有 _chk 後綴的函數,但由於 Dart 完全不使用這些函數,因此它沒有帶或不帶後綴的調用,因此 MobSF 會將程式碼視為包含未強化的調用。)

共享物件應使用 RELRO

#

找不到 libapp.so 二進位檔的 RELRO

Dart 完全不使用正常的程序連結表 (PLT) 或全域偏移表 (GOT) 機制,因此重定位唯讀 (RELRO) 技術對 Dart 來說並沒有太大的意義。

Dart 中與 GOT 等效的是池指標,與 GOT 不同的是,它位於隨機位置,因此更難以利用。

原則上,您可以在使用 Dart FFI 時建立易受攻擊的程式碼,但假設它與 C 程式碼一起使用,而 C 程式碼本身也會適當地使用 RELRO,則正常使用 Dart FFI 也不會容易產生這些問題。

共享物件應使用堆疊金絲雀值

#

找不到 libapp.so 二進位檔的金絲雀

此共享物件沒有新增到堆疊的堆疊金絲雀值。堆疊金絲雀用於偵測和防止利用覆寫返回位址。使用選項 -fstack-protector-all 來啟用堆疊金絲雀。

Dart 不會產生堆疊金絲雀,因為與 C++ 不同,Dart 沒有堆疊配置的陣列(C/C++ 中堆疊粉碎的主要來源)。

在編寫純 Dart 程式碼時(不使用 dart:ffi),您已經擁有比任何 C++ 防禦措施所能提供的更強大的隔離保證,這僅僅是因為純 Dart 程式碼是一種受管理的語言,其中不存在緩衝區溢位之類的問題。

原則上,您可以在使用 Dart FFI 時建立易受攻擊的程式碼,但假設它與 C 程式碼一起使用,而 C 程式碼本身也會適當地使用堆疊金絲雀值,則正常使用 Dart FFI 也不會容易產生這些問題。

程式碼應避免使用 _sscanf_strlen_fopen API

#

二進位檔可能包含下列不安全的 API:_sscanf_strlen_fopen

回報這些問題的工具往往在其掃描中過於簡單化;例如,找到具有這些名稱的自訂函數,並假設它們是指標準函式庫函數。許多 Flutter 的協力廠商相依性都具有名稱類似的函數,會觸發這些檢查。某些出現的情況可能是有效的疑慮,但由於錯誤的肯定結果數量龐大,因此無法從這些工具的輸出判斷。

程式碼應使用 calloc(而非 _malloc)進行記憶體配置

#

二進位檔可能會使用 _malloc 函數,而不是 calloc

記憶體配置是一個細微的主題,必須在效能和對漏洞的彈性之間進行權衡。僅僅使用 malloc 並不一定表示存在安全漏洞。雖然我們歡迎針對使用 calloc 會較佳的情況提供具體的報告(請參閱下文),但在實務上,統一將所有 malloc 調用替換為 calloc 是不適當的。

iOS 二進位檔已設定 Runpath 搜尋路徑 (@rpath)

#

二進位檔已設定 Runpath 搜尋路徑 (@rpath)。在某些情況下,攻擊者可以濫用此功能來執行任意可執行檔,以進行程式碼執行和權限提升。請移除編譯器選項 -rpath 以移除 @rpath

當建置應用程式時,Runpath 搜尋路徑是指連結器搜尋以尋找應用程式所使用動態函式庫 (dylib) 的路徑。依預設,iOS 應用程式會將其設定為 @executable_path/Frameworks,這表示連結器應在應用程式套件內相對於應用程式二進位檔的 Frameworks 目錄中搜尋 dylib。與大多數嵌入式框架或 dylib 一樣,Flutter.framework 引擎會正確地複製到此目錄中。當應用程式執行時,它會載入函式庫二進位檔。

Flutter 應用程式使用預設的 iOS 建置設定 (LD_RUNPATH_SEARCH_PATHS=@executable_path/Frameworks)。

涉及 @rpath 的漏洞不適用於行動設定,因為攻擊者無法存取檔案系統,也無法任意交換這些框架。即使攻擊者以某種方式可以將框架換成惡意的框架,應用程式也會因為程式碼簽署違規而在啟動時當機。

具有 PKCS5/PKCS7 填充漏洞的 CBC

#

我們收到一些含糊的報告,指出某些 Flutter 套件中存在「具有 PKCS5/PKCS7 填充漏洞的 CBC」。

據我們所知,這是由 ExoPlayer 中的 HLS 實作(com.google.android.exoplayer2.source.hls.Aes128DataSource 類別)所觸發。HLS 是 Apple 的串流格式,它定義了 DRM 必須使用的加密類型;這不是漏洞,因為 DRM 並不保護使用者的機器或資料,而僅僅提供混淆,以限制使用者完全使用其軟體和硬體的能力。

應用程式可以讀取和寫入外部儲存空間

#

應用程式可以讀取/寫入外部儲存空間。任何應用程式都可以讀取寫入外部儲存空間的資料。

與任何不受信任來源的資料一樣,您在處理來自外部儲存空間的資料時,應執行輸入驗證。我們強烈建議您不要在動態載入之前將可執行檔或類別檔案儲存在外部儲存空間中。如果您的應用程式確實從外部儲存空間擷取可執行檔,則檔案應在動態載入之前進行簽署和加密驗證。

我們收到報告指出,某些漏洞掃描工具將影像選取器外掛程式讀取和寫入外部儲存空間的能力解釋為一種威脅。

從本機儲存空間讀取影像正是這些外掛程式的目的;這不是漏洞。

應用程式使用 file.delete() 刪除資料

#

當您使用 file.delete 刪除檔案時,只會從檔案系統表中移除對該檔案的參照。該檔案仍然存在於磁碟上,直到其他資料覆寫它為止,使其容易被還原。

某些漏洞掃描工具將相機外掛程式在從裝置相機錄製資料後刪除暫存檔案的行為解釋為安全漏洞。由於影片是由使用者錄製並儲存在使用者的硬體上,因此沒有實際風險。

過時的疑慮

#

本節包含在使用舊版 Dart 和 Flutter 時可能會看到的有效訊息,但在較新版本中不應再看到。如果您在舊版 Dart 或 Flutter 中看到這些訊息,請升級到最新的穩定版本。如果您在目前的穩定版本中看到這些訊息,請回報它們(請參閱本文檔結尾的部分)。

堆疊應設定其 NX 位元

#

共享物件未設定 NX 位元。NX 位元透過將記憶體頁面標示為不可執行,來提供針對利用記憶體損毀漏洞的保護。使用選項 --noexecstack-z noexecstack 將堆疊標示為不可執行。

(來自 MobSF 的訊息具有誤導性;它正在尋找堆疊是否標示為不可執行,而不是共享物件。)

在舊版 Dart 和 Flutter 中,有一個錯誤是 ELF 產生器未發出具有 ~X 許可權的 gnustack 區段,但現在已修正。

回報真實疑慮

#

雖然自動化漏洞掃描工具會報告錯誤的肯定結果,例如上述範例,但我們不能排除存在需要更密切注意的真實問題。如果您發現您認為是合法的安全漏洞的問題,我們將非常感謝您回報它