ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

MASTG 指南:Android 键盘缓存(Keyboard Cache)与敏感输入字段的防护实践

MASTG 指南:Android 键盘缓存(Keyboard Cache)与敏感输入字段的防护实践 文档教程网络安全【免费下载链接】mastgThe OWASP Mobile Application Security Testing Guide (MASTG) is a comprehensive manual for mobile app security testing and reverse engineering. It describes technical processes for verifying the OWASP Mobile Security Weakness Enumeration (MASWE) weaknesses, which are in alignment with the OWASP MASVS.项目地址https://gitcode.com/gh_mirrors/ow/mastg点击查看免费下载在 Android 应用中默认开启的键盘输入建议与自动补全功能会把用户输入的历史内容缓存在输入法如 Gboard的训练缓存数据库中这对密码、PIN 码等敏感字段构成数据泄露风险。本文基于 OWASP Mobile Application Security Testing GuideMASTG的知识条目 MASTG-KNOW-0055系统讲解键盘缓存的成因、通过inputType禁用缓存的三种实现方式XML 布局、传统 View、Jetpack Compose、五类非缓存输入类型及其位掩码解码方法并结合仓库中的静态分析规则与测试用例给出可落地的检测与验证方案。读完本文你将能够在开发阶段正确配置敏感输入字段并在逆向分析阶段通过解码inputType数值与运行 Semgrep 规则快速判断目标应用是否仍存在键盘缓存泄露风险。键盘缓存Android 输入法如何泄露敏感数据当用户向输入框输入内容时Android 系统键盘软件通常会基于此前输入过的数据提供联想建议suggestions与自动补全auto-completion。这种机制对即时通讯类应用非常有用但它默认会保留缓存输入历史用于生成后续建议。在密码、PIN 等敏感数据的输入场景下这一缓存行为会无意间暴露敏感信息——这些数据会被写入输入法自身的训练缓存数据库而非应用沙箱内部应用开发者无法直接控制其生命周期。从 MASTG 的分层看这一主题归属于 MASVS-STORAGE 类别数据存储因为它本质上属于敏感数据被持久化在不受应用控制的存储介质问题MASTG 将其映射为 MASWE-0036UI 元素中的键盘缓存属性引用。相关的最佳实践条目 MASTG-BEST-0019 明确指出对敏感字段使用非缓存输入类型有助于保护敏感数据免于在系统生成的快照snapshots与录制recordings中被暴露。应用可以完全控制这一行为只要为文本输入字段正确配置inputType属性即可。inputType本质上是一个位掩码整数系统键盘正是依据它来决定是否对该字段提供联想与缓存。三种禁用键盘缓存的标准写法无论使用哪种 UI 技术栈核心思路都是为敏感输入字段指定密码类password或禁止建议no suggestions的输入类型。下面分别给出 XML 布局、传统 View 体系与 Jetpack Compose 三种实现。XML 布局android:inputType在 APK 解包后位于res/layout目录的布局文件中可以直接在EditText元素上通过android:inputType属性定义输入类型。例如将输入类型设置为textPassword会自动禁用联想建议与缓存EditText android:idid/password android:layout_widthmatch_parent android:layout_heightwrap_content android:hintstring/password_hint android:inputTypetextPassword /这也是静态分析时最直观的检查对象逆向出的布局 XML 中凡是对敏感字段出现android:inputTypetext或缺少该属性都应当标记为潜在问题。传统 Android View代码中调用setInputType使用传统 View 体系在代码中创建输入框时可通过EditText的inputType属性编程式设置。例如创建一个 PIN 输入框val input EditText(context).apply { hint Enter PIN inputType InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_PASSWORD }这里使用按位或or把类别常量与变体常量组合成完整的输入类型。需要特别警惕的是运行时对inputType的二次赋值可能覆盖布局中的安全配置。如下面这段漏洞代码所示一个字段在初始化时被正确设置为TYPE_CLASS_NUMBER or TYPE_NUMBER_VARIATION_PASSWORD随后又被赋值为TYPE_CLASS_NUMBER从而把 PIN 字段重新变成了可缓存类型val input3 EditText(context).apply { hint Enter PIN (cached) inputType InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_PASSWORD } input3.inputType InputType.TYPE_CLASS_NUMBER // 重新启用缓存这正是仓库 Demo MASTG-DEMO-0064 中刻意构造的陷阱也是 MASTG-TEST-0006 明确要求检查应用代码中是否存在覆盖输入类型的原因findViewById(R.id.KeyBoardCache).setInputType(InputType.TYPE_CLASS_TEXT)这类调用会把字段重置为text从而重新启用键盘缓存。Jetpack ComposeKeyboardOptions与visualTransformationJetpack Compose 不使用EditText而是通过TextField、OutlinedTextField等可组合函数配合keyboardOptions与visualTransformation参数达到同等效果。创建一个无联想建议的密码输入框OutlinedTextField( value password, onValueChange { password it }, label { Text(Enter Password) }, visualTransformation PasswordVisualTransformation(), keyboardOptions KeyboardOptions( keyboardType KeyboardType.Password, autoCorrect false ), modifier Modifier.fillMaxWidth() )其中PasswordVisualTransformation()负责对输入内容做掩码显示keyboardOptions中的KeyboardType.Password指定密码输入类型autoCorrect false则显式关闭自动纠错/联想建议。从源码层面看Compose 的KeyboardType枚举内部会映射到 Android 原生的inputType值。例如KeyboardType.Password对应的映射逻辑为KeyboardType.Password - { this.inputType InputType.TYPE_CLASS_TEXT or EditorInfo.TYPE_TEXT_VARIATION_PASSWORD }也就是说Compose 最终仍会落到与原生 View 相同的InputType位掩码体系上只是 API 形态不同——这一点在逆向分析中极为关键无论应用用哪种 UI 框架编写反编译后最终观察到的都是对setInputType的调用或布局 XML 中的android:inputType属性。非缓存输入类型速查表无论采用上述哪种实现方式下面五类inputType取值应用于EditText都会指示系统禁用联想并阻止缓存XMLandroid:inputTypeCodeInputTypeAPI leveltextNoSuggestionsTYPE_TEXT_FLAG_NO_SUGGESTIONS3textPasswordTYPE_TEXT_VARIATION_PASSWORD3textVisiblePasswordTYPE_TEXT_VARIATION_VISIBLE_PASSWORD3numberPasswordTYPE_NUMBER_VARIATION_PASSWORD11textWebPasswordTYPE_TEXT_VARIATION_WEB_PASSWORD11关于 API level 的注意点MASTG 测试中默认不检查 AndroidManifest 的minSdkVersion因为测试面向现代应用但如果你在测试较老的应用应核对minSdkVersion。例如textWebPassword需要 API level 11否则编译出的应用不会真正生效这些输入类型常量键盘缓存依然会发生详见 MASTG-TEST-0006 的说明。解码inputType逆向分析中的位掩码运算inputType是标志位与类别的按位组合。InputType类中既有标志常量也有类别常量其取值定义在 Android 源码frameworks/base/core/java/android/text/InputType.java中。这三类常量的作用分别为类别常量TYPE_CLASS_*输入类型text、number、phone 等变体常量TYPE_TEXT_VARIATION_*等具体行为password、email、URI 等标志常量TYPE_TEXT_FLAG_*附加修饰禁止联想、多行等。因此inputType的组合方式是类别 变体 标志的按位或。例如inputType InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD其中TYPE_CLASS_TEXT 1TYPE_TEXT_VARIATION_PASSWORD 128结果是1 or 128 129——这个129就是你在反编译代码中看到的数值。反编译后若要解码任意inputType数值可使用三组掩码配合按位与AND运算TYPE_MASK_CLASS0x0000000F提取类别部分TYPE_MASK_VARIATION0x00000FF0提取变体部分TYPE_MASK_FLAGS0x00FFF000提取标志部分。例如在 Python 中快速解码129129 0x0000000F # 1 (TYPE_CLASS_TEXT) 129 0x00000FF0 # 128 (TYPE_TEXT_VARIATION_PASSWORD)仓库 Demo MASTG-DEMO-0064 提供了多组可直接对照的数值18解码为2 (TYPE_CLASS_NUMBER) | 16 (TYPE_NUMBER_VARIATION_PASSWORD)正确的 PIN 配置而2仅解码为TYPE_CLASS_NUMBER可缓存的错误配置1仅解码为TYPE_CLASS_TEXT可缓存的错误配置。把这些数值与上面的速查表对照即可判定目标字段是否使用了非缓存输入类型。静态检测用 Semgrep 规则自动发现setInputType针对代码中动态设置输入类型这一检查点仓库提供了一条现成的 Semgrep 规则 mastg-android-keyboard-cache-input-types.yml其核心是捕获所有setInputType()调用及参数rules: - id: mastg-android-non-caching-input-types severity: WARNING languages: - java metadata: summary: This rule scans all usages of setInputType(). message: [MASVS-STORAGE] Set input type detected ($OBJ) with $ARG patterns: - pattern: $OBJ.setInputType($ARG)在 Demo MASTG-DEMO-0064 中run.sh使用如下命令对反编译后的 Java 代码运行该规则NO_COLORtrue semgrep -c ../../../../rules/mastg-android-keyboard-cache-input-types.yml ./MastgTest_reversed.java output.txt其输出见 output.txt会为每处命中给出行号、反编译代码中的对象名如$this$showPopup_u24lambda_u241或input3、setInputType方法本身以及传入的输入类型数值。该 Demo 的样例代码 MastgTest.kt 构造了三个输入字段——password正确配置为 129、passphrase错误配置为 1、PIN先正确配置为 18 又被覆盖为 2因此规则最终报告 4 处命中。判定逻辑如下PASSsetInputType(129)→TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD禁止缓存正确FAILsetInputType(1)→ 仅TYPE_CLASS_TEXTpassphrase 可被缓存应改为129FAILsetInputType(18)→TYPE_CLASS_NUMBER | TYPE_NUMBER_VARIATION_PASSWORD本身正确但随后setInputType(2)仅保留TYPE_CLASS_NUMBERPIN 可被缓存应保持18。测试用例与完整验证流程MASTG 将上述检查沉淀为一条可执行测试 MASTG-TEST-0258UI 元素中的键盘缓存属性引用属于静态代码分析关联 MASWE-0036、MASTG-BEST-0019 与 MASTG-KNOW-0055。旧版测试 MASTG-TEST-0006MSTG-STORAGE-5 / MASVS-STORAGE-2L1/L2 级别已标记为废弃由前者取代。静态分析步骤对应 MASTG-TEST-0258 的 Steps使用 MASTG-TECH-0013 对应用进行逆向工程使用 MASTG-TECH-0014 在代码中检索相关 API即setInputType调用使用 MASTG-TECH-0007 从应用包中提取布局文件。观察要点若 UI 使用 XML收集所有android:inputTypeXML 属性若 UI 使用代码收集所有setInputType方法调用及其传入的输入类型数值若 UI 使用 Jetpack Compose检查KeyboardOptions构造中的keyboardType与autoCorrect参数。判定标准只要存在处理敏感数据的字段未使用非缓存输入类型测试即判定失败。动态验证补充确认启动应用并点击接收敏感数据的输入框。若键盘弹出联想建议字符串说明该字段的键盘缓存未被禁用同时若无法完全卸载第三方输入法进行验证可留意建议栏的呈现情况作为旁证。实锤取证从输入法缓存数据库中检索泄露数据要确认敏感输入已被缓存这一事实可以在输入字段中反复输入某个特定字符串例如 OWASPMAS然后直接查询输入法Gboard的训练缓存数据库adb shell strings /data/data/com.google.android.inputmethod.latin/databases/trainingcachev3.db | grep -i OWASPMAS若输出类似下面的内容说明输入内容已进入输入法的训练缓存数据库键盘缓存确实未被禁用OWASPMAS OWASPMAS OWASPMAS%这条取证手段与 MASTG-KNOW-0055 中的原始步骤一致可作为静态分析结论的动态佐证先通过inputType位掩码解码与 Semgrep 规则圈定可疑字段再通过缓存数据库检索实锤数据泄露。结语把非缓存输入类型固化为安全基线键盘缓存是 Android 平台上最容易忽视的敏感数据泄露通道之一——它发生在输入法进程而非应用自身且默认开启。开发侧只需为密码、PIN、验证码等敏感字段统一采用textNoSuggestions、textPassword、numberPassword等非缓存输入类型无论 XML、传统 View 还是 Compose即可从源头消除该问题安全测试侧则可结合本文的位掩码解码方法、Semgrep 规则与 MASTG-TEST-0258 的静态检查流程在 CI 或人工审计中持续发现遗漏的敏感输入字段。相关示例与规则均已收录在本仓库的 demos/android/MASVS-STORAGE/MASTG-DEMO-0064、rules 与 tests-beta 目录中可直接作为团队安全基线与测试模板使用。赞分享文档教程网络安全【免费下载链接】mastgThe OWASP Mobile Application Security Testing Guide (MASTG) is a comprehensive manual for mobile app security testing and reverse engineering. It describes technical processes for verifying the OWASP Mobile Security Weakness Enumeration (MASWE) weaknesses, which are in alignment with the OWASP MASVS.项目地址https://gitcode.com/gh_mirrors/ow/mastg点击查看免费下载相关推荐使用 Semgrep 检测 Android 键盘缓存敏感输入MASTG-DEMO-0064 实战解析使用 Semgrep 检测 Android 键盘缓存敏感输入MASTG DEMO 0064 实战解析 MASTG DEMO 0064 是 OWASP MAS文档教程网络安全MASTG iOS 安全实践将敏感输入锁定在系统键盘上MASTG-BEST-0069 深度解读MASTG iOS 安全实践将敏感输入锁定在系统键盘上MASTG BEST 0069 深度解读 本文基于 OWASP Mobile Application文档教程网络安全OWASP MASTG 最佳实践Android ContentProvider 中的 SQL 注入防护指南MASTG-BEST-0039OWASP MASTG 最佳实践Android ContentProvider 中的 SQL 注入防护指南MASTG BEST 0039 ContentP文档教程网络安全上一篇音乐解锁利器3步解决加密音乐播放难题下一篇Python-for-Android跨平台编译架构深度解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表