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 true和shrinkResources 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)。
Phase 7: Inter‑app communication and deep links
App Links / Universal Links
- 在可能的情况下,使用 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_detection、freerasp)检测越狱 (iOS) 和 Root (Android)。 - 对可疑环境做出按比例的响应(功能降级、警告或退出)。
Anti-tamper
- 依靠原生完整性检查(Android 上的 Play Integrity API、iOS 上的 DeviceCheck/App Attest)进行后端认证 (attestation)。
- 将客户端检查视为信号,绝不是唯一的安全控制手段。
Phase 9: Cryptography and randomness
- 使用经过审查的 Dart 加密实现(例如
crypto或pointycastle包),或通过 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()(使用 FlutterfoundationAPI 中的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.yaml、build.gradle、Podfile)的漏洞。 - 为 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包。