Dashboard/Issues/OH-2026-TEL-001
SubmittedCWE-862 — Missing Authorization

CallManagerService 部分方法缺少权限检查

View Upstream Issuegitcode.com/openharmony/telephony_call_manager/issues/1913
CWE:CWE-862 — Missing Authorization
Date:2026-04-29
Reporter:Zirui

漏洞编号:

CWE-862 (Missing Authorization)

漏洞归属组件

services/call_manager_service/src/call_manager_service.cpp

漏洞归属版本

2026.04.23 日期版本

CVSS V3.0分值

多个案例,请看具体描述

漏洞简述

背景

CallManagerService 的大部分方法遵循标准的双步验证模式(参考 DialCall, line 303-352):

  1. TelephonyPermission::CheckCallerIsSystemApp() — 验证调用者是系统应用
  2. TelephonyPermission::CheckPermission(OHOS_PERMISSION_*) — 验证特定权限令牌

但以下方法偏离了这一模式。

具体发现

1. GetProxyObjectPtr() — 无任何权限检查(高风险)

位置: call_manager_service.cpp:1591-1617

该方法在无任何身份验证的情况下,向调用者返回 BluetoothCallService 的原始 IPC 代理对象。任何进程可通过此接口获得蓝牙通话控制的完整访问权限。

sptr<IRemoteObject> CallManagerService::GetProxyObjectPtr(CallManagerProxyType proxyType)
{
    // 无 CheckCallerIsSystemApp,无 CheckPermission
    // ...
    case PROXY_BLUETOOTH_CALL: {
        sptr<BluetoothCallService> ptr = new BluetoothCallService();
        return ptr->AsObject().GetRefPtr();  // 直接返回代理对象
    }
}

影响: 未授权进程可获得 BluetoothCallService 的完整 IPC 接口。

2. MakeCall() — 仅验证系统应用,缺少 PLACE_CALL 权限检查(高风险)

位置: call_manager_service.cpp:369-390

int32_t CallManagerService::MakeCall(std::string number)
{
    if (!TelephonyPermission::CheckCallerIsSystemApp()) {  // 仅此一项检查
        return TELEPHONY_ERR_ILLEGAL_USE_OF_SYSTEM_API;
    }
    // 无 CheckPermission(OHOS_PERMISSION_PLACE_CALL)
    std::string identity = IPCSkeleton::ResetCallingIdentity();  // 提权
    // ... 启动拨号界面,拨打任意号码
}

作为对比,同类方法 DialCall (line 303) 同时执行了 CheckCallerIsSystemApp() (line 305) 和 CheckPermission(OHOS_PERMISSION_PLACE_CALL) (line 318)。MakeCall 缺少后者,且使用了 ResetCallingIdentity() 进行提权。

影响: 任何系统应用(无需 PLACE_CALL 权限)可触发向任意号码拨号。

3. GetCallState() / HasCall() — 无任何权限检查(中风险)

位置:

  • GetCallState: call_manager_service.cpp:449-457
  • HasCall: call_manager_service.cpp:513-526
int32_t CallManagerService::GetCallState()
{
    // 无任何检查,直接返回通话状态
    return callControlManagerPtr_->GetCallState();
}

bool CallManagerService::HasCall(const bool isInCludeVoipCall)
{
    // 无任何检查,返回是否有通话(含 VoIP)
    return callControlManagerPtr_->HasCall();
}

影响: 任何进程可查询用户当前是否在通话中、通话状态(idle/ringing/offhook),以及 VoIP 通话状态。属于用户隐私信息泄露。

4. IsEmergencyPhoneNumber() — 无任何权限检查(低风险)

位置: call_manager_service.cpp:1124-1132

无权限检查即可查询任意号码是否为紧急号码,可能泄露设备运营商/地区信息。

5. FormatPhoneNumber() / FormatPhoneNumberToE164() — 无任何权限检查(低风险)

位置: call_manager_service.cpp:1134-1154

无权限检查即可格式化电话号码,属于非授权 IPC 攻击面。

影响性分析说明

缺少权限检查可能会导致非法获取某些访问权限,比如案例 1 中任何进程可通过此接口获得蓝牙通话控制的完整访问权限

原理分析

多个方法缺少权限检查,权限检查已经有模板: CallManagerService 的大部分方法遵循标准的双步验证模式(参考 DialCall, line 303-352):

  1. TelephonyPermission::CheckCallerIsSystemApp() — 验证调用者是系统应用
  2. TelephonyPermission::CheckPermission(OHOS_PERMISSION_*) — 验证特定权限令牌

受影响版本

规避方案或消减措施

建议修复

为上述方法添加与同类方法一致的双步权限验证,例如:

  • GetProxyObjectPtr: 添加 CheckCallerIsSystemApp() + 适当的权限检查
  • MakeCall: 补充 CheckPermission(OHOS_PERMISSION_PLACE_CALL)
  • GetCallState / HasCall: 添加 CheckCallerIsSystemApp()CheckPermission(OHOS_PERMISSION_GET_TELEPHONY_STATE)