0x01 基礎概述
許多應用程序要求用戶在訪問任何內容之前先在應用程序內部進行身份驗證。根據其中包含的信息的敏感性,應用程序通常有兩種方法:
· 用戶進行一次身份驗證,然后保持身份驗證,直到他們手動注銷為止;
· 用戶保持登錄狀態的時間不會太長,并且在一段時間不活動后必須重新進行身份驗證。
第一種策略雖然對用戶非常方便,但顯然不是很安全。第二種方法相當安全,但是對用戶來說卻是一個負擔,因為他們每次都必須輸入其憑據。實施生物特征認證可以減輕這種負擔,因為認證方法對用戶而言變得相當容易和快速。
開發人員通常不會從頭開始編寫與操作系統的集成,而通常會使用框架或第三方提供的庫。當使用跨平臺的移動應用程序框架(例如Flutter,Xamarin或React Native)時,尤其如此,其中需要在特定于平臺的代碼中實現此類集成。由于身份驗證是一項對安全性至關重要的功能,因此重要的是驗證這些第三方庫是否已安全地實現了所需的功能。
在此博客文章中,我們將首先看一下生物特征認證的基本概念,以便我們隨后可以研究提供生物特征認證支持的多個React Native庫的安全性。
我們分析了五個提供生物特征認證的React Native庫。對于這些庫中的每一個,我們分析了生物識別認證的實現方式以及它是否正確使用操作系統提供的加密原語來保護敏感數據。
我們的分析表明,五個分析的庫中只有一個提供了基于結果的安全生物特征認證。其他庫僅提供基于事件的身份驗證,這是不安全的,因為僅對生物特征認證進行驗證,而實際上并未以密碼方式保護任何數據。
0x02 生物特征識別
生物特征認證允許用戶使用其生物特征數據(指紋或面部識別)對應用進行認證。通常,可以通過兩種不同的方式來實現生物特征認證:
· 基于事件:生物統計API僅將身份驗證嘗試的結果返回給應用程序(“成功”或“失敗”),這種方法被認為是不安全的;
· 基于結果:身份驗證成功后,生物統計API會檢索一些加密對象(例如解密密鑰)并將其返回給應用程序。失敗時,不會返回任何加密對象。
基于事件的身份驗證是不安全的,因為它僅包含返回的布爾值(或類似值)。因此,可以使用代碼工具(例如Frida)通過修改返回值或手動觸發成功流程來繞過它。如果實現是基于事件的,則還意味著敏感信息以不安全的方式存儲在某處:在應用程序從生物識別API接收到“成功”之后,它仍將需要使用一些身份驗證向后端進行用戶身份驗證。一種憑證,將從本地存儲中檢索,無需解密密鑰即可完成此操作,否則,實現將不是基于事件的,這意味著憑據無需適當加密即可存儲在本地存儲中的某個位置。
另一方面,良好的基于結果的生物特征認證將無法通過Frida之類的工具來繞過。要實現基于結果的安全生物特征認證,應用程序必須使用硬件支持的生物特征API。
存儲憑證
盡管我們在此文章中使用“憑證”一詞,但我們并不主張存儲用戶的憑證(即用戶名和密碼)。無論用戶的憑據存儲方式如何,將其存儲在設備上對于高安全性應用程序從來都不是一個好主意。相反,上述“憑證”應該是專用于生物認證的憑證(例如高熵字符串),這些憑證是在生物認證的激活期間生成的。
要在Android上實施基于結果的安全生物身份驗證,必須生成需要用戶身份驗證的加密密鑰。這可以通過使用setUserAuthenticationRequired生成密鑰時的方法來實現。每當應用程序嘗試訪問密鑰時,Android將確保提供有效的生物識別信息。然后必須使用密鑰來執行加密操作,從而解鎖憑據,然后可以將憑據發送到后端。這是通過向CryptoObject生物識別API提供以上一個密鑰開頭的來完成的。例如,BiometricPrompt類提供了一個authenticate方法,該方法采用CryptoObject作為一個論點。然后,可以通過result參數在成功回調方法中獲得對該鍵的引用。可以在f-secure的這篇非常不錯的博客文章中找到有關在Android上實現安全生物特征認證的更多信息。
在iOS上,必須生成一個加密密鑰并將其存儲在key串中。key串中的條目必須設置有訪問控制標志biometryAny。然后必須使用密鑰執行加密操作,以解鎖可發送到后端的憑據。通過向key串查詢受密鑰保護的biometryAnyiOS,iOS將確保用戶使用其生物識別數據解鎖所需的key。或者,我們可以將憑據本身直接存儲在biometryAny保護下,而不是將密碼密鑰存儲在“key串”中。
指紋認證
Android和iOS允許你信任“設備上已注冊的所有指紋”或“設備上當前已注冊的所有指紋”。在后一種情況下,如果添加或刪除了指紋,則加密對象將無法使用。對于Android,默認值為“所有指紋”,而在將指紋添加到設備的情況下,你可以使用setInvalidatedByBiometricEnrollment刪除CryptoObject。對于iOS,可以在biometryAny和biometryCurrentSet之間進行選擇。雖然“當前已注冊”選項是最安全的,但在本文中,我們不會對這種區別給予重視。
基于事件的身份驗證真的不安全嗎?是的。這完全取決于你的移動應用程序的威脅模型。應用程序提供基于結果的身份驗證的要求是OWASP MASVS(MSTG-AUTH-8)中的2級要求。級別2表示你的應用程序正在處理敏感信息,通常用于金融,醫療或政府部門的應用程序。
OWASP MASVS驗證級別
如果你的應用程序使用基于事件的生物特征認證,則將發生特定的攻擊,這些攻擊將使用戶的憑據可供攻擊者使用:
· 使用取證軟件進行物理提取
· 從備份文件中提取數據(例如iTunes備份或adb備份)
· 具有root權限訪問設備的惡意軟件
最后一個示例也將能夠攻擊使用基于結果的生物特征認證的應用程序,因為有可能在憑據已在內存中解密后立即注入到應用程序中,但這種攻擊的門檻比只需復制應用程序的本地存儲。