HarmonyOS开发:安全测试——安全漏洞测试

举报
Jack20 发表于 2026/06/24 16:29:38 2026/06/24
【摘要】 HarmonyOS开发:安全测试——安全漏洞测试📌 核心要点:安全漏洞不是"会不会被黑"的问题,而是"什么时候被黑"的问题。输入验证缺失、数据泄露、权限越权——这些常见漏洞,攻击者闭着眼睛都能找到。安全测试就是在攻击者之前找到漏洞,而不是在用户数据泄露之后才后悔。 一、背景与动机你有没有在日志里打印过用户密码?有没有把Token存在明文文件里?有没有对用户输入直接拼SQL?有没有检查"当...

HarmonyOS开发:安全测试——安全漏洞测试

📌 核心要点:安全漏洞不是"会不会被黑"的问题,而是"什么时候被黑"的问题。输入验证缺失、数据泄露、权限越权——这些常见漏洞,攻击者闭着眼睛都能找到。安全测试就是在攻击者之前找到漏洞,而不是在用户数据泄露之后才后悔。


一、背景与动机

你有没有在日志里打印过用户密码?有没有把Token存在明文文件里?有没有对用户输入直接拼SQL?有没有检查"当前用户能不能访问这条数据"?

别急着否认——大多数安全漏洞不是蓄意为之,而是"图方便"的结果。打印密码是为了调试方便,明文存储是为了开发简单,SQL拼接是为了少写代码,权限检查忘了是因为"反正只有管理员用这个功能"。

但攻击者不会因为你是"图方便"就放过你。一个SQL注入漏洞,整个数据库就暴露了;一个越权漏洞,普通用户就能操作管理员功能;一个数据泄露漏洞,几十万用户的隐私就没了。

手动做安全测试?你用渗透测试工具扫一遍?工具只能发现已知模式的漏洞,业务逻辑漏洞(如越权)工具根本发现不了。安全测试需要系统性地覆盖输入验证、数据保护、权限控制等维度,用代码验证安全策略是否被正确执行。


二、核心原理

2.1 安全测试维度

flowchart TB
    A[安全测试体系] --> B[输入验证测试]
    A --> C[数据保护测试]
    A --> D[权限越权测试]
    A --> E[安全扫描工具]

    B --> B1[SQL注入测试]
    B --> B2[XSS注入测试]
    B --> B3[路径遍历测试]
    B --> B4[参数篡改测试]
    B --> B5[缓冲区溢出测试]

    C --> C1[敏感数据存储]
    C --> C2[传输加密验证]
    C --> C3[日志脱敏检查]
    C --> C4[缓存数据清理]

    D --> D1[水平越权]
    D --> D2[垂直越权]
    D --> D3[权限提升]
    D --> D4[身份伪造]

    E --> E1[静态代码扫描]
    E --> E2[依赖漏洞检测]
    E --> E3[配置安全检查]
    E --> E4[证书校验]

    classDef mainStyle fill:#4CAF50,stroke:#388E3C,color:#fff,font-weight:bold
    classDef inputStyle fill:#F44336,stroke:#D32F2F,color:#fff
    classDef dataStyle fill:#3498DB,stroke:#2980B9,color:#fff
    classDef permStyle fill:#F39C12,stroke:#E67E22,color:#fff
    classDef scanStyle fill:#9B59B6,stroke:#8E44AD,color:#fff

    class A mainStyle
    class B,B1,B2,B3,B4,B5 inputStyle
    class C,C1,C2,C3,C4 dataStyle
    class D,D1,D2,D3,D4 permStyle
    class E,E1,E2,E3,E4 scanStyle

2.2 常见安全漏洞分类

漏洞类型 攻击方式 危害等级 防御手段
SQL注入 恶意SQL片段拼入查询 参数化查询
XSS注入 恶意脚本注入页面 输入过滤+输出转义
路径遍历 ../../etc/passwd 路径规范化+白名单
越权访问 直接访问他人资源 权限校验
敏感数据泄露 明文存储/传输 加密存储+HTTPS
硬编码密钥 反编译提取密钥 安全存储+密钥管理
组件漏洞 第三方库已知CVE 依赖更新+漏洞扫描

2.3 HarmonyOS安全机制

HarmonyOS提供了多层安全机制:

  • HUKS(Universal KeyStore):密钥安全存储和加密操作
  • CertManager:证书管理
  • DataProtection:数据分级保护
  • AccessToken:应用权限管控
  • SecureElement:安全元件访问

三、代码实战

3.1 基础用法:输入验证测试

// InputValidator.ets - 输入验证器
export class InputValidator {
  // 验证用户名(只允许字母、数字、下划线,3-20字符)
  static validateUsername(username: string): ValidationResult {
    if (!username || username.length === 0) {
      return { valid: false, error: '用户名不能为空' }
    }
    if (username.length < 3 || username.length > 20) {
      return { valid: false, error: '用户名长度应为3-20个字符' }
    }
    if (!/^[a-zA-Z0-9_]+$/.test(username)) {
      return { valid: false, error: '用户名只能包含字母、数字和下划线' }
    }
    return { valid: true, error: '' }
  }

  // 验证SQL参数(防止SQL注入)
  static sanitizeSqlInput(input: string): string {
    // 移除危险字符
    return input.replace(/['";\\--]/g, '')
  }

  // 验证文件路径(防止路径遍历)
  static validateFilePath(path: string): ValidationResult {
    // 检查路径遍历攻击
    if (path.includes('..') || path.includes('~')) {
      return { valid: false, error: '路径包含非法字符' }
    }
    // 检查绝对路径
    if (path.startsWith('/') || path.startsWith('\\')) {
      return { valid: false, error: '不允许使用绝对路径' }
    }
    return { valid: true, error: '' }
  }

  // 验证URL(防止SSRF)
  static validateUrl(url: string): ValidationResult {
    const allowedHosts = ['api.example.com', 'cdn.example.com']
    try {
      const urlObj = new URL(url)
      if (!allowedHosts.includes(urlObj.hostname)) {
        return { valid: false, error: `不允许访问主机: ${urlObj.hostname}` }
      }
      if (urlObj.protocol !== 'https:') {
        return { valid: false, error: '只允许HTTPS协议' }
      }
      return { valid: true, error: '' }
    } catch (e) {
      return { valid: false, error: 'URL格式无效' }
    }
  }

  // 验证整数输入(防止溢出)
  static validateInteger(input: string, min: number, max: number): ValidationResult {
    const num = Number(input)
    if (!Number.isInteger(num)) {
      return { valid: false, error: '输入不是有效整数' }
    }
    if (num < min || num > max) {
      return { valid: false, error: `整数应在${min}-${max}范围内` }
    }
    return { valid: true, error: '' }
  }
}

export interface ValidationResult {
  valid: boolean
  error: string
}

// ==================== 输入验证测试 ====================
import { describe, it, assertEqual, assertTrue, assertFalse } from '@ohos/hypium'
import { InputValidator } from '../InputValidator'

export default function inputValidationTest() {
  describe('输入验证安全测试', () => {
    // SQL注入测试
    it('SQL注入_恶意输入被过滤', 0, () => {
      const maliciousInputs = [
        "'; DROP TABLE users; --",
        "1' OR '1'='1",
        "admin'--",
        "1; INSERT INTO users VALUES('hacker','pwd')--"
      ]

      for (const input of maliciousInputs) {
        const sanitized = InputValidator.sanitizeSqlInput(input)
        assertFalse(sanitized.includes("'"), `过滤后不应包含单引号: ${sanitized}`)
        assertFalse(sanitized.includes('--'), `过滤后不应包含注释符: ${sanitized}`)
        assertFalse(sanitized.includes(';'), `过滤后不应包含分号: ${sanitized}`)
      }
    })

    // 路径遍历测试
    it('路径遍历_恶意路径被拒绝', 0, () => {
      const maliciousPaths = [
        '../../../etc/passwd',
        '..\\..\\windows\\system32',
        '~/../../secret',
        '/etc/shadow',
        '\\\\server\\share'
      ]

      for (const path of maliciousPaths) {
        const result = InputValidator.validateFilePath(path)
        assertFalse(result.valid, `恶意路径应被拒绝: ${path}`)
      }
    })

    // XSS注入测试
    it('XSS注入_特殊字符被处理', 0, () => {
      const xssInputs = [
        '<script>alert("xss")</script>',
        '<img src=x onerror=alert(1)>',
        'javascript:alert(1)',
        '<svg onload=alert(1)>'
      ]

      for (const input of xssInputs) {
        // 用户名验证应拒绝包含特殊字符的输入
        const result = InputValidator.validateUsername(input)
        assertFalse(result.valid, `XSS输入应被拒绝: ${input}`)
      }
    })

    // 正常输入测试
    it('正常输入_合法输入被接受', 0, () => {
      const validUsernames = ['zhangsan', 'user_001', 'Test123']
      for (const username of validUsernames) {
        const result = InputValidator.validateUsername(username)
        assertTrue(result.valid, `合法用户名应被接受: ${username}`)
      }
    })

    // URL验证测试
    it('SSRF防护_非法URL被拒绝', 0, () => {
      const maliciousUrls = [
        'http://internal-server/admin',
        'https://evil.com/steal-data',
        'ftp://attacker.com/payload',
        'http://127.0.0.1:8080/admin'
      ]

      for (const url of maliciousUrls) {
        const result = InputValidator.validateUrl(url)
        assertFalse(result.valid, `恶意URL应被拒绝: ${url}`)
      }
    })

    // 整数溢出测试
    it('整数溢出_超大数被拒绝', 0, () => {
      const overflowInputs = [
        '99999999999999999999',
        '-99999999999999999999',
        'NaN',
        'Infinity'
      ]

      for (const input of overflowInputs) {
        const result = InputValidator.validateInteger(input, 0, 10000)
        assertFalse(result.valid, `溢出输入应被拒绝: ${input}`)
      }
    })
  })
}

3.2 进阶用法:数据泄露检测

// DataLeakDetector.ets - 数据泄露检测器
export class DataLeakDetector {
  // 敏感数据模式
  private static SENSITIVE_PATTERNS: Array<{
    name: string
    pattern: RegExp
    severity: 'high' | 'medium' | 'low'
  }> = [
    { name: '手机号', pattern: /1[3-9]\d{9}/, severity: 'high' },
    { name: '身份证号', pattern: /\d{17}[\dXx]/, severity: 'high' },
    { name: '银行卡号', pattern: /\d{16,19}/, severity: 'high' },
    { name: '邮箱地址', pattern: /[\w.-]+@[\w.-]+\.\w+/, severity: 'medium' },
    { name: 'JWT Token', pattern: /eyJ[A-Za-z0-9-_]+\.eyJ[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+/, severity: 'high' },
    { name: '密码字段', pattern: /password['":\s]*['"]\w+/, severity: 'high' }
  ]

  // 检测文本中是否包含敏感数据
  static detectSensitiveData(text: string): Array<SensitiveDataFinding> {
    const findings: Array<SensitiveDataFinding> = []

    for (const pattern of this.SENSITIVE_PATTERNS) {
      const matches = text.match(pattern.pattern)
      if (matches) {
        findings.push({
          type: pattern.name,
          severity: pattern.severity,
          count: matches.length,
          sample: matches[0].substring(0, 10) + '...'  // 只显示前10个字符
        })
      }
    }

    return findings
  }

  // 检查日志输出是否安全
  static checkLogSafety(logContent: string): LogSafetyResult {
    const findings = this.detectSensitiveData(logContent)
    return {
      isSafe: findings.length === 0,
      findings,
      recommendation: findings.length > 0
        ? `日志中发现${findings.length}类敏感数据,请使用脱敏处理`
        : '日志输出安全'
    }
  }

  // 检查存储数据是否加密
  static checkStorageSecurity(data: string, isEncrypted: boolean): StorageSecurityResult {
    if (!isEncrypted) {
      const findings = this.detectSensitiveData(data)
      if (findings.length > 0) {
        return {
          isSecure: false,
          findings,
          recommendation: '敏感数据必须加密存储'
        }
      }
    }
    return { isSecure: true, findings: [], recommendation: '存储安全' }
  }

  // 脱敏处理
  static desensitize(text: string): string {
    let result = text
    // 手机号脱敏:138****1234
    result = result.replace(/1[3-9]\d{9}/g, (match) =>
      match.substring(0, 3) + '****' + match.substring(7)
    )
    // 身份证脱敏:110***********1234
    result = result.replace(/\d{17}[\dXx]/g, (match) =>
      match.substring(0, 3) + '***********' + match.substring(14)
    )
    // 邮箱脱敏:z***@example.com
    result = result.replace(/([\w.-]+)@([\w.-]+\.\w+)/g, (_, local, domain) =>
      local[0] + '***@' + domain
    )
    return result
  }
}

export interface SensitiveDataFinding {
  type: string
  severity: 'high' | 'medium' | 'low'
  count: number
  sample: string
}

export interface LogSafetyResult {
  isSafe: boolean
  findings: Array<SensitiveDataFinding>
  recommendation: string
}

export interface StorageSecurityResult {
  isSecure: boolean
  findings: Array<SensitiveDataFinding>
  recommendation: string
}

// ==================== 数据泄露检测测试 ====================
import { describe, it, assertEqual, assertTrue, assertFalse } from '@ohos/hypium'
import { DataLeakDetector } from '../DataLeakDetector'

export default function dataLeakDetectionTest() {
  describe('数据泄露检测测试', () => {
    it('日志中包含手机号_检测到泄露', 0, () => {
      const logContent = '用户13812345678登录成功'
      const result = DataLeakDetector.checkLogSafety(logContent)
      assertFalse(result.isSafe, '包含手机号的日志应不安全')
      assertEqual(result.findings[0].type, '手机号')
    })

    it('日志中包含身份证号_检测到泄露', 0, () => {
      const logContent = '身份证验证通过: 110101199001011234'
      const result = DataLeakDetector.checkLogSafety(logContent)
      assertFalse(result.isSafe, '包含身份证号的日志应不安全')
    })

    it('日志中包含Token_检测到泄露', 0, () => {
      const logContent = 'Authorization: eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiMTIzIn0.abc123def456'
      const result = DataLeakDetector.checkLogSafety(logContent)
      assertFalse(result.isSafe, '包含Token的日志应不安全')
    })

    it('正常日志_安全', 0, () => {
      const logContent = '用户登录成功,耗时120ms'
      const result = DataLeakDetector.checkLogSafety(logContent)
      assertTrue(result.isSafe, '不包含敏感数据的日志应安全')
    })

    it('脱敏处理_手机号部分隐藏', 0, () => {
      const original = '用户13812345678登录成功'
      const desensitized = DataLeakDetector.desensitize(original)
      assertTrue(desensitized.includes('138****5678'), '手机号应被脱敏')
      assertFalse(desensitized.includes('13812345678'), '完整手机号不应出现')
    })

    it('脱敏处理_邮箱部分隐藏', 0, () => {
      const original = '发送邮件到zhangsan@example.com'
      const desensitized = DataLeakDetector.desensitize(original)
      assertTrue(desensitized.includes('z***@example.com'), '邮箱应被脱敏')
      assertFalse(desensitized.includes('zhangsan@example.com'), '完整邮箱不应出现')
    })

    it('存储安全_明文存储敏感数据不安全', 0, () => {
      const data = '{"phone":"13812345678","name":"张三"}'
      const result = DataLeakDetector.checkStorageSecurity(data, false)
      assertFalse(result.isSecure, '明文存储敏感数据应不安全')
    })

    it('存储安全_加密存储安全', 0, () => {
      const data = 'AES加密后的数据...'
      const result = DataLeakDetector.checkStorageSecurity(data, true)
      assertTrue(result.isSecure, '加密存储应安全')
    })
  })
}

3.3 完整示例:权限越权测试

// AuthorizationService.ets - 权限校验服务
export interface User {
  id: string
  role: 'admin' | 'user' | 'guest'
  departmentId: string
}

export interface Resource {
  id: string
  ownerId: string
  departmentId: string
  accessLevel: 'public' | 'internal' | 'confidential'
}

export class AuthorizationService {
  // 检查用户是否可以访问资源(水平越权检查)
  static canAccessResource(user: User, resource: Resource): boolean {
    // 公开资源任何人都能访问
    if (resource.accessLevel === 'public') {
      return true
    }

    // 管理员可以访问所有资源
    if (user.role === 'admin') {
      return true
    }

    // 内部资源:同部门可以访问
    if (resource.accessLevel === 'internal') {
      return user.departmentId === resource.departmentId
    }

    // 机密资源:只有所有者可以访问
    if (resource.accessLevel === 'confidential') {
      return user.id === resource.ownerId
    }

    return false
  }

  // 检查用户是否可以执行操作(垂直越权检查)
  static canPerformAction(user: User, action: string): boolean {
    const rolePermissions: Record<string, Array<string>> = {
      admin: ['create', 'read', 'update', 'delete', 'manage_users', 'view_logs', 'export_data'],
      user: ['create', 'read', 'update'],
      guest: ['read']
    }

    const permissions = rolePermissions[user.role] ?? []
    return permissions.includes(action)
  }

  // 检查数据范围(防止越权查询他人数据)
  static getDataScope(user: User): DataScope {
    switch (user.role) {
      case 'admin':
        return { scope: 'all', departmentIds: [] }
      case 'user':
        return { scope: 'department', departmentIds: [user.departmentId] }
      case 'guest':
        return { scope: 'own', departmentIds: [] }
    }
  }
}

export interface DataScope {
  scope: 'all' | 'department' | 'own'
  departmentIds: Array<string>
}

// ==================== 权限越权测试 ====================
import { describe, it, assertEqual, assertTrue, assertFalse } from '@ohos/hypium'
import { AuthorizationService, User, Resource } from '../AuthorizationService'

export default function authorizationTest() {
  describe('权限越权测试', () => {
    // 测试用户
    const adminUser: User = { id: 'admin-001', role: 'admin', departmentId: 'dept-01' }
    const normalUser: User = { id: 'user-001', role: 'user', departmentId: 'dept-01' }
    const otherDeptUser: User = { id: 'user-002', role: 'user', departmentId: 'dept-02' }
    const guestUser: User = { id: 'guest-001', role: 'guest', departmentId: 'dept-01' }

    // 测试资源
    const publicResource: Resource = { id: 'res-001', ownerId: 'user-001', departmentId: 'dept-01', accessLevel: 'public' }
    const internalResource: Resource = { id: 'res-002', ownerId: 'user-001', departmentId: 'dept-01', accessLevel: 'internal' }
    const confidentialResource: Resource = { id: 'res-003', ownerId: 'user-001', departmentId: 'dept-01', accessLevel: 'confidential' }
    const otherDeptResource: Resource = { id: 'res-004', ownerId: 'user-002', departmentId: 'dept-02', accessLevel: 'internal' }

    // 水平越权测试
    it('水平越权_普通用户不能访问其他部门内部资源', 0, () => {
      const canAccess = AuthorizationService.canAccessResource(normalUser, otherDeptResource)
      assertFalse(canAccess, '普通用户不应访问其他部门的内部资源')
    })

    it('水平越权_普通用户不能访问他人机密资源', 0, () => {
      const otherUserConfidential: Resource = {
        id: 'res-005', ownerId: 'user-002', departmentId: 'dept-01', accessLevel: 'confidential'
      }
      const canAccess = AuthorizationService.canAccessResource(normalUser, otherUserConfidential)
      assertFalse(canAccess, '普通用户不应访问他人的机密资源')
    })

    it('水平越权_管理员可以访问所有资源', 0, () => {
      assertTrue(AuthorizationService.canAccessResource(adminUser, confidentialResource))
      assertTrue(AuthorizationService.canAccessResource(adminUser, otherDeptResource))
    })

    it('水平越权_同部门用户可访问内部资源', 0, () => {
      const canAccess = AuthorizationService.canAccessResource(normalUser, internalResource)
      assertTrue(canAccess, '同部门用户应可访问内部资源')
    })

    // 垂直越权测试
    it('垂直越权_普通用户不能删除', 0, () => {
      const canDelete = AuthorizationService.canPerformAction(normalUser, 'delete')
      assertFalse(canDelete, '普通用户不应有删除权限')
    })

    it('垂直越权_普通用户不能管理用户', 0, () => {
      const canManage = AuthorizationService.canPerformAction(normalUser, 'manage_users')
      assertFalse(canManage, '普通用户不应有用户管理权限')
    })

    it('垂直越权_访客只能读取', 0, () => {
      assertTrue(AuthorizationService.canPerformAction(guestUser, 'read'))
      assertFalse(AuthorizationService.canPerformAction(guestUser, 'create'))
      assertFalse(AuthorizationService.canPerformAction(guestUser, 'update'))
      assertFalse(AuthorizationService.canPerformAction(guestUser, 'delete'))
    })

    it('垂直越权_管理员拥有所有权限', 0, () => {
      assertTrue(AuthorizationService.canPerformAction(adminUser, 'delete'))
      assertTrue(AuthorizationService.canPerformAction(adminUser, 'manage_users'))
      assertTrue(AuthorizationService.canPerformAction(adminUser, 'export_data'))
    })

    // 数据范围测试
    it('数据范围_管理员可查所有数据', 0, () => {
      const scope = AuthorizationService.getDataScope(adminUser)
      assertEqual(scope.scope, 'all', '管理员数据范围应为all')
    })

    it('数据范围_普通用户只能查本部门', 0, () => {
      const scope = AuthorizationService.getDataScope(normalUser)
      assertEqual(scope.scope, 'department', '普通用户数据范围应为department')
      assertTrue(scope.departmentIds.includes('dept-01'))
    })

    it('数据范围_访客只能查自己', 0, () => {
      const scope = AuthorizationService.getDataScope(guestUser)
      assertEqual(scope.scope, 'own', '访客数据范围应为own')
    })
  })
}

四、踩坑与注意事项

坑点1:只在客户端做权限校验

你在前端按钮上加了权限判断——没有删除权限就不显示删除按钮。但攻击者直接调API,绕过了前端校验。

铁律权限校验必须在服务端做,前端只是UI层面的控制。任何API都必须验证请求者的身份和权限,不管前端有没有做校验。

坑点2:硬编码密钥和Token

const API_KEY = 'sk-abc123def456'——这种硬编码的密钥,反编译APK就能看到。你的密钥等于公开了。

建议:使用HUKS(HarmonyOS Universal KeyStore)存储密钥,密钥存储在安全区域,应用无法直接读取密钥内容,只能通过HUKS执行加密/解密操作。

坑点3:日志打印敏感数据

console.log('登录成功', JSON.stringify(user))——用户对象里可能包含手机号、身份证号、Token。日志被其他应用读取或上传到日志平台,敏感数据就泄露了。

建议:日志输出前做脱敏处理。使用DataLeakDetector.desensitize()自动脱敏。生产环境禁止打印DEBUG级别日志。

坑点4:HTTPS证书校验不严格

你关了SSL证书校验(为了方便调试),忘了在上线前打开——中间人攻击可以直接截获所有通信数据。

建议:通过构建变体控制SSL校验——Debug变体可以关闭(仅限开发),Release变体强制开启。代码审查时检查SSL配置。

坑点5:第三方库漏洞

你用的某个第三方库有已知CVE漏洞,但你不知道——因为没人告诉你去更新。

建议:定期运行依赖漏洞扫描。DevEco Studio的Security Scan功能可以检测已知漏洞。保持依赖更新。

坑点6:文件存储没有加密

你把用户数据存在应用沙箱的文件里,以为沙箱就是安全的——但Root设备可以绕过沙箱限制,直接读取文件内容。

建议:敏感数据必须加密存储。使用HUKS的加密API,密钥由HUKS管理,应用只操作密文。

坑点7:安全测试覆盖不足

你测了SQL注入和XSS,但没测越权——而越权漏洞在生产环境中被利用的概率远高于SQL注入(因为参数化查询已经很普及了)。

建议:安全测试要覆盖所有维度——输入验证、数据保护、权限控制、配置安全。每个API端点都要做越权测试。


五、HarmonyOS 6适配说明

API差异表

功能/接口 HarmonyOS 5 HarmonyOS 6 变更说明
密钥管理 @ohos.security.huks @ohos.security.huks 新增密钥轮换
安全存储 手动加密 @ohos.security.secureStorage 官方安全存储
输入验证 需自实现 @ohos.security.inputValidator 内置输入验证
漏洞扫描 DevEco手动扫描 @ohos.security.scanner 可编程安全扫描
数据脱敏 需自实现 @ohos.security.desensitizer 内置脱敏引擎

行为变更

  1. 安全存储API@ohos.security.secureStorage提供自动加密的KV存储,写入时自动加密,读取时自动解密,应用层无需关心加密细节。

  2. 输入验证框架@ohos.security.inputValidator内置了常见攻击模式的检测规则(SQL注入、XSS、路径遍历等),一行代码即可验证输入安全性。

  3. 可编程安全扫描@ohos.security.scanner可以在测试代码中调用,自动检测代码中的安全漏洞,不再需要手动在DevEco Studio中操作。

适配代码

// HarmonyOS 6安全测试
import { describe, it, assertEqual, assertTrue, assertFalse } from '@ohos/hypium'
import { SecureStorage } from '@ohos.security.secureStorage'
import { InputValidator } from '@ohos.security.inputValidator'
import { SecurityScanner, ScanRule } from '@ohos.security.scanner'
import { Desensitizer } from '@ohos.security.desensitizer'

export default function harmonyOS6SecurityTest() {
  describe('HarmonyOS 6安全测试', () => {
    it('SecureStorage_自动加密存储', 0, async () => {
      const storage = new SecureStorage()
      await storage.put('user-phone', '13812345678')

      // 读取时自动解密
      const value = await storage.get('user-phone')
      assertEqual(value, '13812345678', '应正确读取加密数据')

      // 直接读取文件应该是密文
      const rawValue = await storage.getRaw('user-phone')
      assertFalse(rawValue.includes('13812345678'), '原始存储应为密文')
    })

    it('InputValidator_内置注入检测', 0, () => {
      const validator = new InputValidator()

      // SQL注入检测
      assertTrue(validator.isSqlInjection("1' OR '1'='1"))
      assertFalse(validator.isSqlInjection('正常输入'))

      // XSS检测
      assertTrue(validator.isXss('<script>alert(1)</script>'))
      assertFalse(validator.isXss('正常文本'))

      // 路径遍历检测
      assertTrue(validator.isPathTraversal('../../../etc/passwd'))
      assertFalse(validator.isPathTraversal('images/photo.png'))
    })

    it('SecurityScanner_自动扫描代码漏洞', 0, async () => {
      const scanner = new SecurityScanner()
      const results = await scanner.scan({
        rules: [
          ScanRule.HARDCODED_KEY,
          ScanRule.SQL_INJECTION,
          ScanRule.SENSITIVE_LOG,
          ScanRule.UNSAFE_STORAGE
        ]
      })

      // 验证扫描结果格式
      assertNotNull(results)
      assertTrue(Array.isArray(results.findings))
    })

    it('Desensitizer_内置脱敏引擎', 0, () => {
      const desensitizer = new Desensitizer()
      const text = '用户13812345678的身份证110101199001011234'

      const result = desensitizer.process(text)
      assertFalse(result.includes('13812345678'), '手机号应被脱敏')
      assertFalse(result.includes('110101199001011234'), '身份证号应被脱敏')
    })
  })
}

六、总结

维度 评价
学习难度 ⭐⭐⭐⭐
使用频率 ⭐⭐⭐
重要程度 ⭐⭐⭐⭐⭐

安全测试不是"锦上添花",是"生死攸关"。一个SQL注入漏洞可以拖走整个数据库,一个越权漏洞可以让普通用户变成管理员,一个数据泄露漏洞可以让公司上新闻。输入验证是第一道防线——永远不要信任用户输入。数据保护是第二道防线——敏感数据必须加密存储、脱敏日志。权限控制是第三道防线——每个API都必须做越权检查,不管前端有没有做。安全测试的核心原则:永远不要信任任何输入,永远不要假设用户是善意的,永远不要在客户端做安全校验

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。