跳转至

Flutter 应用安全核对表

阶段 0:治理、环境和 CI/CD

实施 CI 门控

  • 在每次 PR 时运行静态检查 (SAST):flutter analyze、单元/UI 测试、dart pub outdated
  • 当出现 High/Critical 级别的 SAST/SCA/DAST 发现时阻断发布 (release);要求发布分支上零 linter 错误。

密钥处理

  • Dart 源码、pubspec.yaml、原生代码或日志中不得有任何机密信息。
  • 使用环境变量(例如 --dart-define)在构建时注入配置。
  • 在分析数据 (analytics) 中脱敏机密信息。
  • 定期以及在怀疑发生泄露时轮换密钥/令牌。

证据和可追溯性

  • 将扫描报告、SBOM、构建日志和发布说明随每个制品归档。

Scanning automation

  • 将(支持 Flutter 的)移动端 SAST/DAST/SCA 平台集成到 CI/CD 中,以便在每次 PR 和预发布时运行,因 High/Critical 问题自动让检查失效 (fail gates)。

阶段 1:威胁建模、数据分类和清单

  • 分类数据(PII、凭据、令牌、支付)并绘制收集、处理、存储(文件、安全数据库)和传输情况图。
  • 识别信任边界 (trust boundaries):Dart 环境/Isolates、MethodChannels、原生库、插件、后端 API。
  • 清点第三方 pub.dev 包;优先选择维护良好、经验证发布者 (verified publishers) 发布且遵循最小权限原则的插件。
  • 最小化 Dart 包的攻击面。

Phase 2: Build and configuration hardening

Release settings

  • 确保所有生产构建都在启用 AOT 的 release 模式下(flutter build apk/ios --release)编译。
  • 从生产构建中移除开发端点和功能标志 (feature flags)。

Android specific

  • 在 Gradle 中使用 minifyEnabled trueshrinkResources true
  • 仅在 AndroidManifest.xml 中声明必要的权限。
  • networkSecurityConfig 中禁用明文流量。

iOS specific

  • 剥离 (strip) 调试符号和死代码。
  • 仅授予必要的授权 (entitlements)。
  • Info.plist 中设置 NSAllowsArbitraryLoads = false

Phase 3: Local storage and secure storage

安全存储

  • 为所有令牌、敏感 PII 和加密密钥使用 flutter_secure_storage 插件(或等效工具)。
  • Android:确保插件使用由 Keystore 支持的加密 (EncryptedSharedPreferences)。
  • iOS:确保插件以适当的可访问性设置(例如 kSecAttrAccessibleWhenUnlockedThisDeviceOnly)使用 Keychain。

Files and databases

  • 避免在 SharedPreferences 或本地文件中以明文形式存储机密或敏感 PII。
  • 如果数据库存储了敏感数据,则应对其加密(例如带 SQLCipher 的 sqflite)。
  • 不要将机密写入日志,即便是暂时的也不行。

Caches and derived data

  • 避免将 PII 持久化到缓存/临时目录中。
  • 注销时清除缓存/临时目录。

Phase 4: Privacy safeguards (UI, clipboard, screenshots)

  • 在应用切换器中遮蔽敏感 UI(例如,使用 secure_application 插件或原生代码来模糊/隐藏屏幕)。
  • 避免在应用启动时读取剪贴板。
  • 绝不将密码、密钥或长生命周期令牌放在系统剪贴板上。

Phase 5: Network security and TLS/pinning

HTTPS/TLS 强制执行

  • 对所有应用通信强制使用 HTTPS。Dart 默认的 HTTP 客户端强制执行 TLS,但必须配置为拒绝不良证书。
  • 绝不在生产环境中绕过证书检查(badCertificateCallback)。

证书固定

  • 实施 SSL/TLS 证书锁定(例如,通过在 SecurityContext 对象中检查 SHA-256)。
  • 验证针对 MITM 场景和过期/已轮换的叶 (leaf) 证书的抵抗力。
  • 规划安全的证书锁定轮换和回退 (fallbacks) 方案。

Cookies and tokens

  • 避免在设备上使用长生命周期的不记名令牌 (bearer tokens)。

阶段 6:身份验证、授权和会话

身份验证流程

  • 针对公共身份验证流,使用带 PKCE 的 OAuth2/OIDC(例如使用 flutter_appauth)。
  • 绝不将客户端机密 (client secrets) 或与身份验证相关的 API 密钥嵌入到 Dart 源码中。
  • 在身份验证时,优先选择系统浏览器组件(Chrome Custom Tabs、SafariViewController)而非应用内 WebViews。

令牌

  • 使用短生命周期的访问令牌 (access tokens)。
  • 安全地存储刷新令牌 (refresh tokens)(例如,flutter_secure_storage)。
  • 在注销、设备变更和发生可疑活动时,轮换并使令牌失效。

授权

  • 强制在服务器端进行授权;将 Flutter 应用的状态视为不受信任 (untrusted)。

  • 在可能的情况下,使用 Android App Links 和 iOS Universal Links,而不是自定义 URL 方案。
  • 在 Dart 代码中验证所有传入链接的来源和参数。

Custom schemes and intents

  • 如果使用了自定义方案,请确保对所有传入数据和数据类型进行稳健的验证。
  • 防御 URL 劫持 (URL hijacking) 和开放重定向 (open redirects)。

Phase 8: Reverse engineering and tamper resilience

Code obfuscation

  • 确保 Flutter release 模式将 Dart 编译为原生 AOT 代码(Android/iOS)。
  • 利用 Flutter 的混淆支持(flutter build apk --obfuscate --split-debug-info=/<dir>)来隐藏业务逻辑和类名。

环境检查

  • 使用受信任的插件(例如 flutter_jailbreak_detectionfreerasp)检测越狱 (iOS) 和 Root (Android)。
  • 对可疑环境做出按比例的响应(功能降级、警告或退出)。

Anti-tamper

  • 依靠原生完整性检查(Android 上的 Play Integrity API、iOS 上的 DeviceCheck/App Attest)进行后端认证 (attestation)。
  • 将客户端检查视为信号,绝不是唯一的安全控制手段。

Phase 9: Cryptography and randomness

  • 使用经过审查的 Dart 加密实现(例如 cryptopointycastle 包),或通过 MethodChannels 依赖原生平台原语。
  • 使用 Dart 的加密安全 RNG (Random.secure())。
  • 为对称加密使用现代模式(例如 AES-GCM)。
  • 绝不重复使用 IVs 或硬编码加密密钥。

Phase 10: Permissions, notifications, and identifiers

Privacy‑related permissions

  • 在即将使用时 (point-of-use) 请求权限,并清楚解释应用上下文。
  • 仅在严格必要时限制访问设备传感器(位置、相机、麦克风)。

Identifiers

  • 避免绑定设备硬件 ID;使用特定于应用且可重置的标识符。

通知

  • 最小化推送通知有效负载中的敏感数据;依靠在打开时获取 (fetch-on-open)。

Phase 11: Logging, analytics, and crash reporting

日志规范

  • 在 release 构建中禁用调试日志和 Dart print()(使用 Flutter foundation API 中的 kReleaseMode / kDebugMode)。
  • 从分析事件 (analytics events) 和崩溃报告(例如 Firebase Crashlytics、Sentry)中脱敏 PII 和机密信息。
  • 确保混淆映射文件 (--split-debug-info) 被安全地保存在服务器端以用于崩溃反混淆,而不要随应用一起发布。

Phase 12: Testing, DAST, and runtime verification

Interception tests

  • 验证应用对抗 MITM 攻击的抵抗力(确保在代理进行拦截且没有特殊信任配置时,Dart 的网络连接会失败)。

API 滥用测试

  • 针对支持 Flutter 应用的后端 API 测试缺乏限流 (rate limiting)、批量赋值 (mass assignment) 和授权漏洞 (IDOR/BOLA)。

Dynamic analysis

  • 运行移动端 DAST(可检查 Dart HTTP 客户端流量)以识别配置错误的 API 和数据泄漏。
  • 导出 DAST 证据以进行优先级分类和重测 (retests)。

Phase 13: SBOM, and evidence

SBOM 与依赖项

  • 监控 Dart 依赖项和原生组件(pubspec.yamlbuild.gradlePodfile)的漏洞。
  • 为 Flutter/Dart 包生成 SBOM。

证据包

  • 将分析 (SAST/DAST) 制品附加到发布记录 (release record) 中。
  • 将 SBOM 附加到发布记录中。

从业者快速参考

  • Config: AOT release 模式,利用 kReleaseMode 隐藏日志/端点。开启 --obfuscate
  • Data: 始终使用 flutter_secure_storage 或原生加密桥接;绝不在 prefs/SQflite 中存放明文 PII。
  • Network: 始终 HTTPS;通过 SecurityContext 锁定证书;在生产环境中绝对不使用可绕过的 badCertificateCallback
  • Auth: 为 OAuth (flutter_appauth) 使用系统浏览器 + PKCE。无硬编码机密。
  • Tamper: Root/越狱检测(freerasp 等),后端认证 (Play Integrity / DeviceCheck)。
  • Privacy: 模糊后台截屏,清除剪贴板数据,请求及时的 (JIT) 权限。
  • Dart/Flutter: 在授权决策上不要信任前端(API 必须验证)。依赖经过审查且有所限制的 pub.dev 包。