鸿蒙应用安全编码专题系列之Web组件URL加载安全

0 评论 377 浏览 0 收藏 11 分钟

在鸿蒙应用开发中,Web 组件(WebView)是加载 H5 页面的核心载体。Android、iOS 等平台因 WebView 误用引发的安全漏洞已屡见不鲜,而鸿蒙系统上的应用也面临类似的安全风险,若未做好防护,极易引发数据泄露、恶意攻击等安全问题。

本原创文章帖发布在华为开发者联盟社区,欢迎开发者前往访问评论交流,更多与该内容相关讨论,请点击原帖查看:鸿蒙应用安全编码专题文章汇总 | 华为开发者联盟

背景介绍

在鸿蒙应用开发中,Web 组件(WebView)是加载 H5 页面的核心载体。Android、iOS 等平台因 WebView 误用引发的安全漏洞已屡见不鲜,而鸿蒙系统上的应用也面临类似的安全风险,若未做好防护,极易引发数据泄露、恶意攻击等安全问题。

一、鸿蒙 WebView 常见 URL 加载安全问题

  • 任意 URL 跳转漏洞:外部传入 URL 未做白名单校验,可直接跳转至钓鱼、恶意网页,窃取用户信息或执行恶意操作。
  • 越界跳转风险:未拦截页面内重定向、链接跳转,可信页面可被动跳转至不可信地址,突破初始安全管控。
  • 未校验协议引发漏洞:加载javascript:data:协议易注入恶意 JS 代码;加载file://协议可读取本地文件;加载 deeplink、applink 等链接,会唤起恶意应用或成为攻击其他应用的跳板。
  • JavaScriptProxy 安全漏洞:注册敏感 JSBridge后,恶意网页可利用该能力调用应用的敏感功能,造成权限越界。
  • 隐私数据泄露:WebView 缓存、Cookie、密码凭证未及时清理,残留数据易被窃取,导致用户隐私泄露。

上述漏洞的核心防护手段为白名单管控,即仅允许 WebView 加载可信域名地址。但白名单的校验内容、方式、时机若存在缺陷,仍可被轻易绕过。

二、常见白名单校验不安全场景

(一)未校验协议

仅校验 URL 域名是否在白名单内,忽略协议校验,是最典型的绕过场景。攻击者可构造伪装域名的恶意协议 URL,利用域名匹配绕过校验,实际加载恶意地址。该场景下,仅校验域名无法杜绝协议层面的攻击,必须同步校验协议合法性

错误示例代码如下,其中link是要校验的url,域名满足要求时,才允许加载

let urlObject = new uri.URI(link);
            if ('www.vmall.com' === urlObject.host) {
              this.controller.loadUrl(link);
            }

攻击方式

构造link如下,通过上述方式获取当前url的host是www.vmall.com,满足上面的要求。但是最后会加载后面的 https://www.baidu.com,进而绕过了域名白名单校验。

let link = "javascript://www.vmall.com/%0d%0awindow.location.href=\'https://www.baidu.com\'";

通过此案例说明,除了域名,还要对url的协议进行安全校验。建议通过白名单机制校验,仅允许https的url加载。如果用黑名单机制,通常也存在各种绕过方式。

正确示例代码如下,同时校验域名和协议

let link = 'https://www.baidu.com/';
            let urlObject = new uri.URI(link);
            if ('www.baidu.com' === urlObject.host && 'https' === urlObject.scheme) {
              this.controller.loadUrl(link);
            }

(二)校验不完整

仅在 URL首次加载时校验协议与域名,未拦截页面重定向、内部跳转后的二次 URL。跳转后的地址若脱离可信范围,原有白名单将完全失效,无法实现全流程安全管控。此时需要对跳转后的地址进行拦截并校验。

Web组件提供了onLoadIntercept()接口来拦截,详情可参考:管理页面跳转及浏览记录导航-管理网页加载与浏览记录-ArkWeb(方舟Web)-应用框架 – 华为HarmonyOS开发者

正确的示例代码如下:

        .onLoadIntercept((event) => {
          if (event) {
            console.info('onLoadIntercept url:' + event.data.getRequestUrl())
            let urlObject = new uri.URI(event.data.getRequestUrl());
            if ('www.baidu.com' === urlObject.host && 'https' === urlObject.scheme) {
              // 返回false表示允许加载
              return false;
            }
          }
          // 返回true表示不允许加载
          return true;
        })

通过上述2个地方的校验可以确保Web组件加载每个URL都在控制范围内。但是在实际开发过程中,通常会出现校验不全或者校验遗漏等问题,是否有一个方案可以直接帮我们自动校验呢?

三、鸿蒙 WebView 安全实现方案

针对上述校验漏洞,鸿蒙 Web 组件提供系统级白名单接口,实现全流程 URL 管控。

(一)核心接口:setUrlTrustList

该接口为鸿蒙官方提供的 URL 白名单配置方法,配置后 Web 组件会自动校验所有加载及跳转 URL,校验不通过则拦截并展示告警页面,无需开发者手动拦截所有跳转场景。接口支持 JSON 格式配置,可精准指定协议、域名、端口、路径。

setUrlTrustList接口详情如下,参考:Class (WebviewController)-@ohos.web.webview (Webview)-ArkTS API-ArkWeb(方舟Web)-应用框架 – 华为HarmonyOS开发者

setUrlTrustListsetUrlTrustList(urlTrustList: string): void

设置当前web的url白名单,只有白名单内的url才能允许加载/跳转,否则将拦截并弹出告警页。

系统能力: SystemCapability.Web.Webview.Core

参数:

参数名 类型 必填 说明
urlTrustList string url白名单列表,使用json格式配置,最大支持10MB。

白名单设置接口为覆盖方式,多次调用接口时,以最后一次设置为准。

当本参数为空字符串时,表示取消白名单,放行所有url的访问。

json格式示例:

{

“UrlPermissionList”: [

{

“scheme”: “https”,

“host”: “www.example1.com”,

“port”: 443,

“path”: “pathA/pathB”

},

{

“scheme”: “http”,

“host”: “www.example2.com”,

“port”: 80,

“path”: “test1/test2/test3”

}

]

}

因此,可通过调用 setUrlTrustList 来配置白名单。

示例代码如下:

        .onControllerAttached(() => {
          console.info('onControllerAttached execute')
          let urltrustList: string = "{\"UrlPermissionList\":[{\"scheme\":\"https\", \"host\":\"www.baidu.com\"}]}"
          this.controller.setUrlTrustList(urltrustList)
        })

当跳转的URL不在上述白名单范围内时,会弹窗如下告警页面。

cke_2171.png

但是此API存在一个问题是不会拦截和校验javascript等协议,因此还需要在URL初次加载前进行协议的白名单校验,仅允许https协议。

(二)最终安全实现逻辑

最终的正确的示例代码如下(仅是代码片段,非完整的代码):

  • URL 加载前协议校验:仅放行https协议,拦截javascript:file:等所有非法协议,从源头阻断协议类攻击。
  • 白名单配置:通过setUrlTrustList配置可信域名,且白名单内仅保留https协议,由系统自动校验全量 URL 加载与跳转,弥补手动校验遗漏。
//加载前校验下协议,仅允许https协议
let urlObject = new uri.URI(link);
if ('https' === urlObject.scheme) {
  this.controller.loadUrl(link);
}

//Web组件初始化时,通过setUrlTrustList配置白名单
.onControllerAttached(() => {
  console.info('onControllerAttached execute')
  let urltrustList: string = "{\"UrlPermissionList\":[{\"scheme\":\"https\", \"host\":\"www.baidu.com\"}]}"
  this.controller.setUrlTrustList(urltrustList)
})

安全建议

基于上述分析,应用在使用Web组件时,为确保加载的URL均是白名单内的URL,有如下几点安全建议:

  •  URL 首次加载场景(Web 组件直接加载、WebViewController 加载),加载前必须校验协议,仅允许 https 协议,拒绝其他所有协议请求。
  • 调用setUrlTrustList配置域名白名单,白名单内严格限定https协议,依托系统能力实现全流程 URL 自动校验与拦截。
  • 禁止依赖黑名单机制防护,其绕过风险远高于白名单,仅通过白名单实现最小权限管控。

 

其他鸿蒙应用安全编码专题文章请参考:

https://developer.huawei.com/consumer/cn/blog//topic/03207416677214221

更多精彩内容,请关注人人都是产品经理微信公众号或下载App
评论
评论请登录
  1. 目前还没评论,等你发挥!