使用 semgrep 检测 Android 安全锁屏 API:基于 OWASP MASTG 的 KeyguardManager 与 BiometricManager 静态分析实战

发布时间:2026/10/6 15:59:25

使用 semgrep 检测 Android 安全锁屏 API:基于 OWASP MASTG 的 KeyguardManager 与 BiometricManager 静态分析实战 文档教程网络安全【免费下载链接】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点击查看免费下载本指南以 OWASP MASTG 仓库中的 MASTG-DEMO-0028 演示为核心完整讲解如何通过 semgrep 静态扫描 Android 应用中对KeyguardManager.isDeviceSecure与BiometricManager.canAuthenticate的调用从而验证设备访问安全策略Device-Access-Security Policy。读完本文你将掌握 MASTG 中检测安全锁屏 API 引用测试MASTG-TEST-0247的完整落地流程从规则文件、样本源码、反编译产物到命令行执行与结果判定。为什么需要检测安全锁屏 API处理敏感信息的移动应用应运行在可信且安全的环境中。为此应用可以通过查询系统状态来实施设备访问安全策略检查项通常包括PIN/密码保护的设备锁定、较新的 Android 系统版本、USB 调试是否开启、设备加密状态以及设备是否被 Root 等。在 MASTG V1 中这一主题由 MASTG-TEST-0012MSTG-STORAGE-11Level 2覆盖该测试在 MASTG V2 中已被弃用并拆分为 MASTG-TEST-0247 与 MASTG-TEST-0249 两个新测试。MASTG-TEST-0247 的核心论断是如果应用不调用任何 API 来验证安全锁屏是否存在则该测试失败。换句话说一个宣称只在有安全锁屏的设备上运行的应用其代码中必须出现可验证的 API 引用痕迹——这正是本演示要回答的问题如何用静态分析工具自动找出这些引用样本程序两种 Android 安全锁屏检测 API演示样本位于 MastgTest.kt是一个用 Kotlin 编写的MastgTest类封装了两种互补的检测手段package org.owasp.mastestapp import android.app.KeyguardManager import android.content.Context import android.hardware.biometrics.BiometricManager import android.os.Build class MastgTest(private val context: Context) { fun mastgTest(): String { val isLocked isDeviceSecure(context) val biometricStatus checkStrongBiometricStatus() return Device has a passcode: $isLocked\n\n Biometric status: $biometricStatus } fun isDeviceSecure(context: Context): Boolean { val keyguardManager context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager return keyguardManager.isDeviceSecure } fun checkStrongBiometricStatus(): String { if (Build.VERSION.SDK_INT Build.VERSION_CODES.R) { val biometricManager context.getSystemService(BiometricManager::class.java) val result biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG) return when (result) { BiometricManager.BIOMETRIC_SUCCESS - BIOMETRIC_SUCCESS - Strong biometric authentication is available. BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE - BIOMETRIC_ERROR_NO_HARDWARE - No biometric hardware available. BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE - BIOMETRIC_ERROR_HW_UNAVAILABLE - Biometric hardware is currently unavailable. BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED - BIOMETRIC_ERROR_NONE_ENROLLED - No biometrics enrolled. else - Unknown biometric status: $result } } else { return Strong biometric authentication check is not supported on this API level. } } }检测路径一KeyguardManager.isDeviceSecureisDeviceSecure(context)通过context.getSystemService(Context.KEYGUARD_SERVICE)获取KeyguardManager实例然后读取其isDeviceSecure属性。该方法返回布尔值true表示设备已设置 PIN、图案或密码等安全锁屏false表示设备未设置任何安全锁。这是判断设备是否被锁定保护最直接、最经典的方式。检测路径二BiometricManager.canAuthenticatecheckStrongBiometricStatus()使用BiometricManager检查强生物识别指纹、人脸、虹膜是否可用且已录入凭据。代码中对 API 级别做了显式门槛Build.VERSION.SDK_INT Build.VERSION_CODES.R即 Android 11 / API 30 及以上低于该级别直接返回不支持。返回值语义如下表常量数值反编译产物中可见含义BIOMETRIC_SUCCESS0强生物识别可用BIOMETRIC_ERROR_HW_UNAVAILABLE1生物识别硬件当前不可用BIOMETRIC_ERROR_NONE_ENROLLED11未录入任何生物识别凭据BIOMETRIC_ERROR_NO_HARDWARE12无生物识别硬件补充原理由于 Android 的生物识别认证以安全锁屏为兜底fallbackBiometricManager.canAuthenticate可以充当KeyguardManager不可用或受设备厂商限制时的替代检查。但需要注意——应用无法在系统层面强制用户开启生物识别只能通过 BiometricPrompt 声明了android.permission.USE_BIOMETRIC权限这是使用生物识别 API 的必要前提。semgrep 规则如何精确匹配这两类 API 调用本演示使用 semgrepMASTG-TOOL-0110一款可扫描 Java、Kotlin 与 Swift 的静态代码扫描器执行规则 mastg-android-device-passcode-present.yml。规则全文如下rules: - id: mastg-android-device-passcode-present languages: - java severity: INFO metadata: summary: This rule searches for API that checks whether the device passcode is set. message: [MASVS-STORAGE] Make sure to verify that your app runs on a device with a passcode set pattern-either: - pattern: | $X.getSystemService(keyguard); ... $Y.isDeviceSecure(); - pattern: | BiometricManager $BM (BiometricManager) $X.getSystemService(BiometricManager.class); ... $BM.canAuthenticate($VAL);规则设计要点languages: [java]规则目标语言为 Java。由于实际扫描的是反编译后的 Java 代码MastgTest_reversed.java这一设定与工作流完全匹配severity: INFO该规则定位为信息级提示用于确认存在而非标记漏洞这与 MASTG-TEST-0247 的测试目标找出 API 引用一致pattern-either两个模式取任一命中即触发。模式一用$X.getSystemService(keyguard)配合后续$Y.isDeviceSecure()匹配 KeyguardManager 检查模式二用BiometricManager的类型转换与服务获取配合canAuthenticate($VAL)匹配生物识别检查。模式中的$X、$Y、$BM、$VAL是 semgrep 的元变量metavariable...表示允许中间存在任意代码段——这正是静态分析放宽上下文、聚焦关键调用对的典型写法message命中时输出的提示文案标注了对应的 MASVS 控制域MASVS-STORAGE提醒开发者确认应用确实运行在设置了密码passcode的设备上。实战步骤对反编译产物执行 semgrep 扫描演示的运行脚本 run.sh 只有一条命令NO_COLORtrue semgrep -c ../../../../rules/mastg-android-device-passcode-present.yml ./MastgTest_reversed.java output.txt命令各参数含义参数作用NO_COLORtrue禁用终端颜色输出保证结果文件为纯文本便于后续处理与归档semgrep调用 semgrep 扫描器MASTG-TOOL-0110-c 规则文件指定要加载的 YAML 规则文件-c即--config./MastgTest_reversed.java扫描目标反编译后的 Java 源码文件 output.txt将扫描结果重定向写入文件为什么扫描的是反编译后的 Java工作流遵循 MASTG 标准的静态分析流程先用逆向工程技术对应 MASTG-TECH-0013将 APK 反编译再在反编译产物上搜索相关 API对应 MASTG-TECH-0014。仓库中同时保留了 MastgTest_reversed.java 这一反编译产物——它由 Kotlin 字节码反编译而来可读性与 Java 源码几乎一致。从中可以清楚地看到 Kotlin 源码是如何被翻译成 Java 语义的public final boolean isDeviceSecure(Context context) { Intrinsics.checkNotNullParameter(context, context); Object systemService context.getSystemService(keyguard); Intrinsics.checkNotNull(systemService, null cannot be cast to non-null type android.app.KeyguardManager); KeyguardManager keyguardManager (KeyguardManager) systemService; return keyguardManager.isDeviceSecure(); } public final String checkStrongBiometricStatus() { if (Build.VERSION.SDK_INT 30) { BiometricManager biometricManager (BiometricManager) this.context.getSystemService(BiometricManager.class); int result biometricManager.canAuthenticate(15); // switch (result) { ... } } return Strong biometric authentication check is not supported on this API level.; }几个值得注意的细节Kotlin 的isDeviceSecure属性访问被编译为keyguardManager.isDeviceSecure()方法调用context.getSystemService(Context.KEYGUARD_SERVICE)被编译为context.getSystemService(keyguard)字符串形式这正是规则模式一中的匹配锚点BiometricManager.Authenticators.BIOMETRIC_STRONG编译为整型常量15在规则中由元变量$VAL匹配Kotlin 编译器插入了Intrinsics.checkNotNullParameter/Intrinsics.checkNotNull空值检查反编译产物中保留了Metadata注解——这些都属于静态分析时需要辨别、但在本规则命中范围内无碍的噪音。观察结果两条命中的输出解析扫描结束后output.txt 记录了完整的 semgrep 报告┌─────────────────┐ │ 2 Code Findings │ └─────────────────┘ MastgTest_reversed.java ❱ rules.mastg-android-device-passcode-present [MASVS-STORAGE] Make sure to verify that your app runs on a device with a passcode set 30┆ Object systemService context.getSystemService(keyguard); 31┆ Intrinsics.checkNotNull(systemService, null cannot be cast to non-null type android.app.KeyguardManager); 32┆ KeyguardManager keyguardManager (KeyguardManager) systemService; 33┆ return keyguardManager.isDeviceSecure(); ⋮┆---------------------------------------- 38┆ BiometricManager biometricManager (BiometricManager) this.context.getSystemService(BiometricManager.class); 39┆ int result biometricManager.canAuthenticate(15);报告共产生2 条 Code Findings全部命中在MastgTest_reversed.java命中 1第 30–33 行getSystemService(keyguard)到keyguardManager.isDeviceSecure()的调用链对应KeyguardManager安全锁屏检查命中 2第 38–39 行getSystemService(BiometricManager.class)到canAuthenticate(15)的调用链对应强生物识别可用性检查。每条命中都同时给出了触发规则的 message[MASVS-STORAGE] Make sure to verify that your app runs on a device with a passcode set与精确到行的源码上下文方便审查者直接定位代码位置。结果评估测试通过的标准演示给出的判定结论是测试通过pass。判定依据完全来自扫描输出中对安全锁屏 API 的引用证据具体为KeyguardManager.isDeviceSecure—— 出现在反编译产物的第 33 行return keyguardManager.isDeviceSecure();BiometricManager.canAuthenticate—— 出现在第 39 行int result biometricManager.canAuthenticate(15);。这与 MASTG-TEST-0247 的评估标准严格对应测试失败的条件是应用未使用任何 API 验证安全锁屏是否存在一旦扫描器在反编译代码中确认了上述任一或全部API 引用即可判定为通过。本样本同时覆盖了两条检测路径属于完整达标的实现。延伸思考从静态证据到安全结论从源码结构看本演示还揭示了移动安全测试中的两层思维证据链闭环MASTG 的演示DEMO与测试用例TEST一一对应——DEMO 提供可复现的样本与命令TEST 给出测试目标与判定标准规则rules则封装了可移植的检测逻辑。三者共同构成规则驱动、样本验证、结果可审计的静态分析工作流有引用≠已强制本测试只验证 API 引用是否存在静态证据并不验证应用是否真正执行了这些检查并据此阻断敏感操作动态行为。如需验证检查是否可被绕过应进一步结合动态分析对应原 MASTG-TEST-0012 中若检查可被绕过则必须验证的说明。实践中审查者还应核对应用是否通过BiometricPrompt强制生物识别认证、是否将认证与 Android KeyStore 密钥访问绑定才能形成完整的设备访问安全评估。参考资源演示文档MASTG-DEMO-0028样本源码MastgTest.kt / MastgTest_reversed.java运行脚本与结果run.sh / output.txtsemgrep 规则mastg-android-device-passcode-present.yml对应测试用例MASTG-TEST-0247V2与已弃用的 MASTG-TEST-0012V1MSTG-STORAGE-11工具与技术背景MASTG-TOOL-0110semgrep、MASTG-TECH-0108Taint Analysis赞分享文档教程网络安全【免费下载链接】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点击查看免费下载相关推荐RIOT OS 板级支持详解STM32 Nucleo-F070RBnucleo-f070rb硬件资源、外设配置与烧录实战RIOT OS 板级支持详解STM32 Nucleo F070RBnucleo f070rb硬件资源、外设配置与烧录实战 导读 本文围绕 RIOT OS文档教程网络安全Android 对象反序列化漏洞检测实战OWASP MASTG MASTG-DEMO-0100 与 semgrep 静态分析Android 对象反序列化漏洞检测实战OWASP MASTG MASTG DEMO 0100 与 semgrep 静态分析 本篇技术指南围绕 OWASP 移文档教程网络安全openpilot 完整安装指南如何把普通汽车升级出车道保持辅助openpilot 完整安装指南如何把普通汽车升级出车道保持辅助 高速上长时间握方向盘的手会酸城市拥堵里反复刹车踩油的右腿会麻你大概也会想这些无聊的部分文档教程网络安全上一篇三步搞定《明日方舟》公开招募MAA智能助手让你的招募效率提升300%下一篇大麦自动抢票工具实操指南环境安装、配置拆解与排错一次讲清创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/6 15:54:25

MuPDF C 多线程渲染实战:主线程读页 + 每页一线程并行输出 PNG

图形学图像处理 【免费下载链接】mupdf mupdf mirror 项目地址: https://gitcode.com/gh_mirrors/mu/mupdf 点击查看 免费下载 MuPDF 是一个轻量级、模块化的 PDF/XPS/CBZ/EPUB 渲染引擎,其 C API 刻意不绑定任何具体线程框架,多线程能力完全…

2026/10/6 17:14:30

Spring事务失效的7个坑与底层原理:从JDBC到分布式事务

1. 事务失效的七宗罪:我踩过的坑,你大概率也会踩先讲个真实事故。几年前我维护过一个电商订单系统,线上出了一个诡异的bug:用户支付成功后,订单状态正常更新,但库存却莫名其妙多扣了一次。代码看起来完全没…

2026/10/6 17:14:30

R+ggplot2复现NC风格分组小提琴图:从数据到出图

做科研图表复现这事,我一直觉得最忌讳的就是只盯着别人的图“照猫画虎”,不知道图层背后为什么要这么叠。Nature Communications 里那类分组小提琴图,乍看就是几个“胖葫芦”并排摆在一起,可真要自己动手从数据一步步画出来&#…

2026/10/6 17:14:30

锂电池保护IC工作原理与实战排障指南

1. 为什么一块锂电池敢直接接上5V充电器?——保护IC才是真正的“守门人”你拆开过任何一块标称3.7V的锂电池吗?比如旧手机电池、蓝牙耳机电芯、或者电动工具里的18650?大概率会看到一块指甲盖大小的黑色小芯片,焊在电池正极引出线…

2026/10/6 17:14:30

数据结构实战速查手册:从逻辑到代码的四层映射

简介:本资源是一份面向计算机专业学生与考研备考者的《数据结构》核心知识点精要总结,聚焦课程基础概念、逻辑与存储结构、典型运算及算法复杂度分析等高频考点。内容覆盖概论、线性表、栈与队列三大核心章节,系统梳理数据元素/数据项定义、A…

2026/10/6 17:14:30

HTML转EXE打包全攻略:从Electron到Tauri的开箱即用方案

做前端的、做产品的,甚至只是帮领导做点小工具的朋友,最近都在问我同一个问题:我手上有个HTML页面,怎么给客户、同事、老总一个能双击就打开的EXE?这需求说起来轻巧,但真落地全是坑——有人随手找了个网页打…

2026/10/6 17:09:29

Agent-Reach 实战:用 Python 打造命令行 AI Agent 工具

1. 从零认识 Agent-Reach:一个把 AI Agent 拉进命令行的工具第一次看到 Agent-Reach 这个名字,我下意识把它拆成了两半:Agent 和 Reach。Agent 是当下最热的 AI 智能体,Reach 是“触达、够得着”的意思。合起来,它想解…

2026/10/5 6:32:56

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/6 4:01:51

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/5 17:38:27

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 0:03:23

MR25H40CDF+STM32F031C6工业级高可靠数据存储方案

1. 项目概述:为什么在工业现场非得用 MR25H40CDF 配 STM32F031C6 做数据存储?在工厂产线的 PLC 控制柜里、在风电变流器的散热片背面、在矿井监测终端的金属外壳下,你经常能看到一块指甲盖大小的黑色芯片——它既不是 Flash,也不是…

2026/10/6 0:03:23

MRAM+STM32工业断电数据保全实战指南

1. 项目概述:为什么在工业现场非得用 MR25H40CDF 配 STM32F031C6 做数据存储?在工厂产线的PLC柜里、在野外无人值守的环境监测终端里、在高速运转的包装机控制板上,你经常能看到一块指甲盖大小的黑色芯片,旁边贴着“MR25H40CDF”丝…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑