flawopen.com/Teardowns/cve-2026-65995-osmand-aidl-authorization
CVE-2026-65995:OsmAnd AIDL 授权绕过
OsmAnd 5.3.3 会自动批准导出的 Android AIDL 服务中的未知调用方,使设备上已安装的任意应用都能触及位置和文件操作。公开通告确认问题已修复,但未说明首个修复版本,也未发布 CVSS 分数。
想象大楼前台本应核对访客名单,却在每位新访客到达时直接把他加入许可名单。OsmAnd 的服务对同一手机上的应用做了类似的事:它把未知调用方登记为已启用,再开放集成接口。修复应要求明确批准,并将批准绑定到调用方真实的 Android 身份。
核心概念与专有名词
AIDL- Android Interface Definition Language:一种通过 Binder IPC 让一个 Android 进程调用另一个进程所暴露方法的机制。
导出的服务- 其他应用可以绑定的 Android 服务。敏感方法必须由权限或同等强度的调用方检查保护。
调用方 UID- 操作系统分配给应用进程的身份。服务应从 Binder 获取 UID,不能相信调用方自行提供的包名。
CWE-862- FlawOpen 对共享授权边界缺失所作的编辑分类。GHSL 将
CWE-862列为多个弱点之一;其通告未发布 CVSS 分数。
框架映射
- FlawOpen 对 MITRE CWE 的概念性映射;没有厂商或 CVE 记录将此弱点编号分配给本研究演示。 CWE-862
根本原因剖析 (Root Cause)
GitHub Security Lab 测试了 OsmAnd 5.3.3,发现导出的 OsmandAidlServiceV2 没有 Android 权限,且 OsmandAidlApi.isAppEnabled() 会以 enabled=true 创建未知 ConnectedApp。由于 getApi() 依据此检查放行 AIDL 调用,新出现的本地应用会被保存为已授权,而不是在用户批准前拒绝。GHSL 称这使 97 个 AIDL 方法暴露,包括返回位置/导航数据的方法和存在路径遍历问题的文件操作。攻击者必须先在同一设备安装应用,但该应用无需 OsmAnd 的位置权限或额外用户操作。GHSL 描述的文件影响限于 OsmAnd 存储沙箱,并非整个设备文件系统。维护者于 2026 年 6 月 28 日确认已修复,但通告未指出首个修复版本。没有发布 CVSS 分数;FlawOpen 基于位置数据泄露和影响完整性的操作,将严重性编辑性评为高。CWE-862 是 FlawOpen 的主要编辑映射,并非 GHSL 只指定了这一种弱点。
攻击执行流程分解
本地应用连接导出的服务
易受影响的服务在没有 Android 权限的情况下导出。同一设备上已安装的应用可连接,而无需请求 OsmAnd 的位置权限。
检查逻辑自行创建授权
遇到未知包名时,isAppEnabled() 会创建并持久化 enabled=true 的 ConnectedApp。检查逻辑反而授予了它本应验证的访问权。
共享边界开放多种能力
getApi() 使用该结果处理 AIDL 调用。GHSL 表示该路径可到达 97 个方法,包括 getAppInfo() 和文件复制操作。
影响范围遵循已证实前提
恶意应用必须已经安装在设备上。GHSL 记录了位置/导航信息泄露和 OsmAnd 沙箱内的文件影响;未证明可访问整个设备或客户设备遭到真实攻击。
源代码对比:漏洞与安全实现
易受影响代码摘自 GHSL 对所测 5.3.3 版本的分析。下方示例是最小化的默认拒绝策略示意,不是 OsmAnd 补丁或完整授权实现:批准流程必须验证 UID、已安装包签名、用户同意以及每个方法所需的权限范围。生产服务应在 Binder 边界执行授权,并单独限制敏感方法。GHSL 确认问题已修复,但没有公布完整补丁或首个修复版本;请升级到受支持版本并核实供应方的最新说明。代码仅作教学用途,不含利用代码或位置/文件载荷。
源码摘录: 方法:isAppEnabled()
public boolean isAppEnabled(@NonNull String pack) {
ConnectedApp connectedApp = connectedApps.get(pack);
if (connectedApp == null) {
connectedApp = new ConnectedApp(app, pack, true);
connectedApps.put(pack, connectedApp);
saveConnectedApps();
}
return connectedApp.isEnabled();
}
private final Set<Integer> approvedCallerUids = new HashSet<>();
private boolean isAppEnabled() {
// 仅在用户明确同意并完成身份验证后填写。
return approvedCallerUids.contains(Binder.getCallingUid());
}
工程与系统安全加固清单
- ✓将 OsmAnd 更新到当前受支持版本。GHSL 确认问题已修复,但未说明首个修复版本;不要仅根据通告日期推断最低修复版本。
- ✓Android 服务应默认拒绝未知 Binder UID。只有在用户明确批准并验证已安装包的签名后才授予访问权限。
- ✓在导出服务边界执行授权,并逐个限制 AIDL 方法;通用授权不能自动开放位置、日志或文件操作。
- ✓将参数中的包名视为不可信输入。使用
Binder.getCallingUid()获取身份,并验证包名与 UID、签名证书之间的绑定。 - ✓将文件操作限制在应用拥有的规范化根目录中,并拒绝越界路径;授权检查不能代替路径验证。
- ✓检查 Android manifest 中无权限保护的导出服务,并测试首次调用、撤销批准、重新安装/签名变更以及每个敏感 AIDL 方法。
- ✓通告描述的是研究人员的 PoC,并非已确认攻击客户设备。调查本地迹象时,不要仅凭漏洞披露就认定设备已被入侵。