一、背景介绍
UIAbility组件是鸿蒙应用中包含用户界面(UI)的核心应用组件,主要承担与用户交互的功能,同时也是应用与其他应用进行跨应用交互的核心入口,其配置安全性直接影响应用整体安全边界。
若UIAbility在注册配置时,将exported属性设置为true,则该组件将处于对外暴露状态,允许其他应用发起交互请求。此时,恶意应用可通过拉起该UIAbility并传入非法参数实施攻击;若该暴露的UIAbility同时配置了deeplink或applink,攻击者还可通过远程链路发起攻击,进一步扩大安全风险。
从应用安全防护视角来看,暴露的UIAbility是鸿蒙应用最核心的安全暴露面,其配置不当或校验缺失,极易成为恶意攻击的突破口。
因此,若UIAbility无需与其他应用进行跨应用交互,应明确将exported属性配置为false。
若UIAbility因业务需求必须对外暴露、与其他应用交互,理论上可通过配置permissions权限对其进行访问控制。但由于鸿蒙系统暂不支持应用自定义权限,对于普通应用而言,通常无法通过权限配置实现对暴露UIAbility的有效防护。
基于上述现状,若应用的UIAbility必须对外暴露,且需接收外部应用传入的参数进行业务处理,则必须对传入参数进行严格的合法性校验,防止参数注入等攻击;若应用可明确该暴露UIAbility的合法调用方范围,则需从want对象中获取调用方(拉起方)的身份信息并进行安全校验,确保仅允许合法应用发起调用。
针对调用方身份校验,实际开发中常出现校验方法不规范、校验逻辑不完整的问题,易导致攻击绕过。以下重点分析常见的不安全校验方式,并给出安全合规的实现方案。
二、不安全的校验方式及风险分析
2.1 仅校验调用方包名(校验不完整)
当其他应用拉起本应用的UIAbility时,开发者可从want对象中获取调用方的包名(bundleName),并以此作为唯一校验依据。

典型不安全校验示例代码如下:
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(DOMAIN, TAG, 'EntryAbility onCreate');
const callerBundleName1 = want.parameters?.['ohos.aafwk.param.callerBundleName'];
if (callerBundleName1 === 'com.example.callerapp') {
// 仅校验包名,无其他校验逻辑
}
}
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
const callerBundleName1 = want.parameters?.['ohos.aafwk.param.callerBundleName'];
if (callerBundleName1 === 'com.example.callerapp') {
// 仅校验包名,无其他校验逻辑
}
}
该校验方式存在明显安全隐患:尽管在鸿蒙系统中仿冒应用包名的难度较高,但并非完全不可实现。攻击者可通过技术手段仿冒合法应用包名,绕过该校验并发起恶意调用,因此仅校验调用方包名不足以保障安全。
2.2 校验包名+签名,但签名信息从本地读取(分布式场景绕过)
为弥补仅校验包名的不足,部分开发者会结合应用签名信息进行校验,认为包名与签名结合即可实现绝对安全——鸿蒙应用的签名信息包含多个安全字段,具备不可仿冒、不可篡改的特性。
参考:BundleInfo-bundleManager-接口依赖的元素及定义-ArkTS API-Ability Kit(程序框架服务)-应用框架 – 华为HarmonyOS开发者

典型不安全校验示例代码如下(从本地读取签名信息):先获取调用方包名,然后调用getBundleInfoSync获取其签名信息,然后进行校验
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(DOMAIN, TAG, 'EntryAbility onCreate');
const callerBundleName1 = want.parameters?.['ohos.aafwk.param.callerBundleName'];
if (callerBundleName1 === 'com.example.callerapp') {
let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_SIGNATURE_INFO;
let userId = 100;
try {
// 从本地获取调用方包名对应的签名信息
let data = bundleManager.getBundleInfoSync('com.example.callerapp', bundleFlags, userId);
// 校验签名信息中的appId是否合法
if (data?.signatureInfo?.appId === '123456789') {
// 执行后续业务逻辑
}
} catch (err) {
let message = (err as BusinessError).message;
hilog.error(0x0000, 'testTag', 'getBundleInfoSync failed: %{public}s', message);
}
}
}
核心安全问题
上述代码在本地场景下可实现有效校验,但未考虑鸿蒙系统的分布式特性——鸿蒙分布式服务(Distributed Service Kit)支持多设备登录同一账号并组网后,实现跨设备应用拉起功能(跨端拉起)。
详情参考:Distributed Service Kit简介-Distributed Service Kit(分布式管理服务)-网络-系统 – 华为HarmonyOS开发者
攻击场景示例:假设有设备A和设备B,设备A上部署应用1(采用上述校验方式),攻击者在设备B上仿冒应用2(仅仿冒包名,无法仿冒签名),通过调用getAvailableDeviceListSync接口获取设备A的deviceId,再调用startAbility接口(在want中传入deviceId参数),远程拉起设备A上的应用1。此时,应用1会从本地读取合法应用2的签名信息,而非远程仿冒应用2的签名信息,导致校验绕过,攻击成功。
攻击流程图如下:

该攻击可成功的核心原因的是:应用1的校验逻辑未适配分布式场景,仅读取本地设备上目标包名的签名信息,未获取远程拉起场景下调用方的真实签名信息,存在校验遗漏。
三、安全的校验实现方案
解决上述分布式场景校验绕过问题的核心,是获取远程拉起场景下调用方的真实签名信息。鸿蒙系统中,want对象不仅包含调用方的包名信息,还携带调用方的签名相关信息(跨设备拉起时,该签名信息为远程设备上调用方的真实信息,可确保不可篡改)。详见下图。

因此,只需从want对象中同时读取调用方的包名和签名相关信息(如appId),进行联合校验,即可覆盖本地及分布式场景,实现安全校验。
安全校验示例代码如下:
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(DOMAIN, TAG, 'EntryAbility onCreate');
// 从want中读取调用方包名和签名相关的appId
const callerBundleName1 = want.parameters?.['ohos.aafwk.param.callerBundleName'];
const callerAppId = want.parameters?.['ohos.aafwk.param.callerAppId'];
// 联合校验包名和appId(签名信息)
if (callerBundleName1 === 'com.example.callerapp' && callerAppId === '123456789') {
hilog.info(DOMAIN, TAG, 'caller is correct');
// 执行合法调用后的业务逻辑
}
}
四、安全建议
基于上述分析,为保障UIAbility组件的交互安全,结合鸿蒙应用开发场景,提出以下安全编码建议:
- 对于无需与其他应用交互的UIAbility,必须显式将
exported属性配置为false,杜绝不必要的安全暴露。 - 若UIAbility因业务需求必须对外暴露,需对外部传入的所有参数进行充分的合法性校验,防止参数注入、非法数据篡改等攻击。
- 若已知UIAbility的合法调用方范围,需对调用方身份进行严格校验,且需满足以下三点要求:
- 校验逻辑需结合调用方包名与签名信息(如appId),不可仅校验包名;
- 调用方的包名和签名信息,必须从
want对象中直接读取,不可从本地获取(避免分布式场景绕过); - 需在
onCreate和onNewWant两个回调中均实现相同的校验逻辑,确保全场景覆盖。
五、参考文档
- exported和permissions配置:module.json5配置文件-应用配置文件(Stage模型)-开发基础知识-基础入门 – 华为HarmonyOS开发者
- want信息:@ohos.app.ability.Want (Want)-通用能力的接口(推荐)-ArkTS API-Ability Kit(程序框架服务)-应用框架 – 华为HarmonyOS开发者、docs/zh-cn/application-dev/reference/apis-ability-kit/js-apis-app-ability-want.md-代码预览-docs:基于OpenHarmony生态的开发者文档项目 – AtomGit | GitCode
- 应用签名信息:BundleInfo-bundleManager-接口依赖的元素及定义-ArkTS API-Ability Kit(程序框架服务)-应用框架 – 华为HarmonyOS开发者
- 跨设备连接UIAbility开发指南:跨设备连接UIAbility开发指南-应用跨设备连接管理-Distributed Service Kit(分布式管理服务)-网络-系统 – 华为HarmonyOS开发者
其他鸿蒙应用安全编码专题文章参考:https://developer.huawei.com/consumer/cn/blog//topic/03207416677214221

起点课堂会员权益




