一、测试主要目的
客户端数据本地存储安全测试的主要目的是系统性地验证:敏感数据是否在本地被不必要地存储?如果必须存储,其存储方式是否足够安全(加密、隔离)?以及存储的数据是否会意外泄露给其他应用或用户?
二、测试范围和攻击面
测试需覆盖App在设备上所有可能存储数据的区域,主要包括:
内部存储:App私有的沙盒目录,其他App通常无法访问。
外部存储:设备共享的存储空间,其他App和用户可能有权访问。
偏好设置:用于存储简单键值对数据的文件。
数据库:如SQLite数据库文件。
进程内存:运行时存储在内存中的数据。
系统日志:App运行时输出的调试和运行日志。
缓存数据:内部缓存和外部缓存。
备份文件:操作系统或备份工具为App创建的备份数据。
密钥库:系统提供的安全存储区域,如AndroidKeystore/iOSKeychain。
三、专业测试方法论和测试点
测试过程应模拟攻击者的思维,结合静态分析和动态分析技术。
阶段一:信息收集和静态分析
反编译和代码审计
操作:使用工具(如Jadx、Ghidra、IDAPro)对App安装包进行反编译或反汇编。
检查项:
搜索代码中和存储相关的API调用(如SharedPreferences,FileOutputStream,SQLiteOpenHelper,NSUserDefaults,NSFileManager)。
识别硬编码的加密密钥、密码、API令牌等。
分析自定义加密算法的实现,评估其强度。
检查数据存储路径的构建逻辑,判断是否可能存储到外部空间。
敏感数据流跟踪
操作:在代码中定位敏感数据(如身份证号、会话令牌、密码)的生成或接收点,手动跟踪其在整个App中的流向,直至其被写入存储或发送出去。
阶段二:动态运行时的分析
在设备上运行App,并执行各种操作,同时监控数据的变化。
文件系统检查
操作:在获取Root或越狱权限的测试设备上,使用文件管理器或ADB命令,完整遍历App的私有目录和共享目录。
检查项:
全面文件扫描:逐一检查所有新创建或修改的文件,特别是数据库、XML、JSON和文本文件。使用grep或strings命令搜索明文敏感信息。
数据库文件分析:使用SQLite浏览器打开发现的数据库文件,检查所有表和数据。注意可能经过简单编码(如Base64)的数据。
偏好设置文件检查:查看shared_prefs目录下的XML文件,确认其中是否包含敏感信息。
密钥库和安全硬件评估
操作:检查App对平台提供的安全存储设施的使用情况。
检查项:
密钥管理:验证用于加密本地数据的密钥是否存储在AndroidKeystore或iOSKeychain中。评估密钥的生成、使用和销毁逻辑。
密钥属性:对于Android,检查密钥是否设置了setUserAuthenticationRequired(true),从而要求生物识别验证后才能使用,提供了更高安全性。
进程内存检查
操作:在App运行并处理敏感数据时,使用内存转储工具获取其进程内存。
检查项:对内存镜像进行字符串搜索,查找敏感的明文数据,如密码、令牌和私人信息。这可以验证敏感信息是否在内存中停留过久而未及时清理。
系统日志监控
操作:在App执行关键操作时,使用logcat等工具实时捕获系统日志。
检查项:检查日志输出中是否意外包含了敏感信息,如完整的网络请求/响应、用户输入、堆栈跟踪中的内部信息等。
备份安全测试
操作:使用ADB命令为App创建备份(adbbackup),然后解包备份文件进行检查。
检查项:确认App是否在配置中允许了备份(android:allowBackup),如果允许,备份数据中是否包含敏感信息,以及这些信息在备份中是否被加密。
阶段三:交互和集成测试
跨应用数据泄露测试
操作:编写一个简单的测试App,尝试访问被测App存储在外部存储或ContentProvider中的数据。
检查项:验证被测App是否通过不恰当的权限设置(如MODE_WORLD_READABLE),将其私有数据暴露给其他应用。
残留数据清理测试
操作:执行登录、浏览敏感数据、退出登录/卸载等一系列操作。
检查项:
退出登录后:检查本地是否仍残留之前的用户数据、会话令牌等。
卸载App后:确认其所有的私有目录和文件是否被系统彻底清除。
四、测试工具
静态分析:Jadx、MobSF、Ghidra
动态分析:Frida、Objection、ADB、AndroidStudioProfiler
文件浏览:RootExplorer、SQLiteBrowser
内存分析:Fridump、Volatility
网络抓包:BurpSuite、Charles(用于辅助验证数据是否在传输前从本地正确读取)
五、测试预期和风险评估
通过以上测试,预期会发现以下几类风险:
高风险:明文存储用户凭证、个人身份信息、金融数据;加密密钥硬编码;备份数据未加密。
中风险:日志泄露敏感信息;缓存中保留过久的敏感数据;残留数据未清理。
低风险:内部存储的私有数据使用了弱加密算法。
六、测试建议
在测试报告之外,应提供加固建议:
最小化存储原则:除非绝对必要,否则不在客户端存储敏感数据。
优先使用系统密钥库:使用AndroidKeystore或iOSKeychain来保护加密密钥。
使用经过验证的强加密算法:如AES-GCM,并搭配安全的密钥派生函数。
禁用备份或保护备份数据:在AndroidManifest.xml中设置android:allowBackup="false",或对备份内容进行加密。
禁止日志输出敏感信息:在发布版本中关闭调试日志或进行脱敏处理。
及时清理内存和缓存:在不再需要时,立即覆盖并释放包含敏感数据的内存缓冲区;定期清理缓存。
客户端数据本地存储安全测试是一个多层次深度的探测过程。要求测试人员需要理解移动操作系统的安全机制,还需具备逆向工程和密码学知识,通过模拟真实攻击者的手段,系统地发现和消除数据在“静止”状态下的安全隐患,从而构建起App安全防御。