【HarmonyOS 5】鸿蒙检测URL是否为恶意地址

249 阅读4分钟

【HarmonyOS 5】鸿蒙检测URL是否为恶意地址

##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财#

一、前言

从现实案例来看,恶意 URL 的危害已渗透至日常生活的各个角落。不少用户因不慎点击 APP 内伪装成 "限时秒杀"" 福利领取 "的虚假链接,瞬间陷入诈骗陷阱 —— 某知名购物 APP 曾曝光用户因点击仿冒官方的" 秒杀链接 ",账户资金在短时间内被盗刷数万元,此类事件不仅对用户造成直接经济损失,更引发公众对 APP 安全防护能力的信任危机。

与此同时,钓鱼网站往往借助短信、邮件等高频触达渠道,将精心包装的欺诈性链接推送给用户:伪装成银行通知、政务平台的钓鱼链接常常以" 账户异常需验证 ""重要文件需下载" 等话术诱导点击,一旦用户上钩,轻则个人信息泄露,重则导致整个数字资产体系陷入风险漩涡,部分企业甚至因用户数据泄露事件面临巨额赔偿与品牌声誉的断崖式下跌。

应用通过华为 HarmonyOS 的Device Security Kit提供的checkUrlThreat 接口,可检测 URL 是否为恶意网址(如钓鱼、恶意软件链接等),并根据检测结果提示或拦截用户访问。

二、业务流程与使用

1.首先需要在AGC平台给对应项目应用,进行安全检测服务的开通:

登录AppGallery Connect( developer.huawei.com/consumer/cn… )网站,选择“我的项目”。在项目列表中找到需要开通Device Security服务的项目。 在这里插入图片描述

在这里插入图片描述 之后重新生成调试Profile,在项目中手动进行签名证书的配置,就可使用该接口了。否则会try catch提示Permission Denied。

2.创建safetyDetect.UrlCheckRequest配置需要检测的Url数组,调用safetyDetect.checkUrlThreat接口异步请求检测: 在这里插入图片描述

import { safetyDetect } from '@kit.DeviceSecurityKit'; // URL检测模块
import { BusinessError } from '@kit.BasicServicesKit'; // 错误处理模块
import { hilog } from '@kit.PerformanceAnalysisKit'; // 日志模块

const TAG = "SafetyDetectJsTest";
const req: safetyDetect.UrlCheckRequest = { urls: ['https://test1.com'] }; // 待检测URL数组
try {
  hilog.info(0x0000, TAG, 'CheckUrlThreat begin.');
  const data = await safetyDetect.checkUrlThreat(req); // 发起检测
  // 处理成功结果:输出URL及风险类型(如NORMAL=0、PHISHING=1等)
  hilog.info(0x0000, TAG, 'Succeeded in checkUrlThreat: %s %d', data.results[0].url, data.results[0].threat);
} catch (err) {
  // 处理错误:输出错误码和信息
  const e: BusinessError = err as BusinessError;
  hilog.error(0x0000, TAG, 'CheckUrlThreat failed: %d %s', e.code, e.message);
}

3.注意事项: 调用频率: 每个应用在每个设备上每天最多调用 1 万次接口。 并发调用: 每个设备上最多支持 5 个并发调用。

三、源码示例:

在这里插入图片描述

import { safetyDetect } from '@kit.DeviceSecurityKit'
import { promptAction } from '@kit.ArkUI'
import { BusinessError } from '@kit.BasicServicesKit'


@Entry
@Component
struct Index {
  @State inputUrl: string = ''  // URL输入值
  @State result: string = ''    // 检测结果文本
  @State isChecking: boolean = false  // 检测状态
  @State threatType: safetyDetect.UrlThreatType | null = null  // 威胁类型(对应文档枚举值)

  // 检测URL风险(真实接口调用)
  async checkUrlSecurity() {
    if (!this.isValidUrl(this.inputUrl)) {
      this.showToast('请输入有效的URL(需包含http/https)');
      return;
    }

    this.isChecking = true;
    const TAG = 'UrlThreatDemo';
    const req: safetyDetect.UrlCheckRequest = { urls: [this.inputUrl] };  // 文档要求的请求格式

    try {
      // 调用文档中的checkUrlThreat接口
      const response: safetyDetect.UrlCheckResponse = await safetyDetect.checkUrlThreat(req);

      this.threatType = response.results[0]?.threat;

      // 枚举值解析结果
      this.result = `检测结果:\nURL:${this.inputUrl}\n风险类型:${this.getThreatName(this.threatType)}`;

      // 拦截钓鱼/恶意软件链接
      if (this.threatType === safetyDetect.UrlThreatType.PHISHING || this.threatType === safetyDetect.UrlThreatType.MALWARE) {
        this.showToast(`检测到${this.getThreatName(this.threatType)},已禁止访问!`);
        // 此处可添加实际拦截逻辑(如阻止页面跳转)
      }
    } catch (err) {
      const error = err as BusinessError;
      console.error(TAG, `接口调用失败:Code=${error.code}, Msg=${error.message}`);
      this.result = `检测失败:${error.message}`;
    } finally {
      this.isChecking = false;
    }
  }

  // URL格式校验
  private isValidUrl(url: string): boolean {
    const pattern = /^(https?:\/\/)/;
    return pattern.test(url);
  }

  // 获取威胁类型名称(对应文档枚举值)
  private getThreatName(threat: safetyDetect.UrlThreatType): string {
    switch (threat) {
      case safetyDetect.UrlThreatType.NORMAL: return 'NORMAL(正常)';
      case safetyDetect.UrlThreatType.PHISHING: return 'PHISHING(钓鱼网站)';
      case safetyDetect.UrlThreatType.MALWARE: return 'MALWARE(恶意软件)';
      default: return 'OTHERS(其他风险)';
    }
  }

  // 提示框
  private showToast(msg: string) {
    promptAction.showToast({
      message: msg
    });
  }

  build() {
    Column({ space: 24 }) {
      // 标题
      Text('URL恶意性检测')
        .fontSize(28)
        .fontWeight(500)
        .margin({ top: 40 })

      // URL输入框
      TextInput({
        text: this.inputUrl,
        placeholder: '请输入URL(如https://example.com)'
      })
        .fontSize(16)
        .padding(12)
        .margin({ top: 24 })
        .border({ width: 1, color: '#E0E0E0' })
        .borderRadius(8)
        .onChange((value) => this.inputUrl = value)

      // 检测按钮(带状态控制)
      Button(this.isChecking ? '检测中...' : '开始检测')
        .fontSize(16)
        .padding(12)
        .margin({ top: 24 })
        .width('70%')
        .backgroundColor(this.isChecking ? '#D0D0D0' : '#007DFF')
        .fontColor('white')
        .borderRadius(24)
        .touchable(this.isChecking)
        .onClick(() => this.checkUrlSecurity())

      // 结果展示区域
      Text(this.result)
        .fontSize(14)
        .lineHeight(22)
        .margin({ top: 24 })
        .padding(16)
        .width('90%')
        .border({ width: 1, color: this.getResultBorderColor() })
        .borderRadius(8)
        .flexGrow(1)

    }
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .backgroundColor('#F5F5F5')
  }

  // 根据威胁类型获取边框颜色(交互优化)
  private getResultBorderColor(): string {
    if (this.threatType === safetyDetect.UrlThreatType.NORMAL) return '#4CAF50'; // 绿色
    if ([safetyDetect.UrlThreatType.PHISHING, safetyDetect.UrlThreatType.MALWARE].includes(this.threatType ?? safetyDetect.UrlThreatType.NORMAL))
      return '#FF4444'; // 红色
    return '#FF9800'; // 橙色(其他风险)
  }
}