对React Native 生物识别库的安全性分析研究
2021-06-03
来源: 嘶吼专业版
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权限访问设备的恶意软件
最后一个示例也将能够攻击使用基于结果的生物特征认证的应用程序,因为有可能在凭据已在内存中解密后立即注入到应用程序中,但这种攻击的门槛比只需复制应用程序的本地存储。

