Aller au contenu

Liste de contrôle de sécurité pour les applications Flutter

Phase 0 : Gouvernance, environnement et CI/CD

Appliquer des portes d'intégration continue (CI gates)

  • Exécuter des analyses statiques (SAST) sur chaque PR : flutter analyze, tests unitaires/UI, dart pub outdated.
  • Bloquer les versions (releases) en cas de découvertes de sévérité élevée ou critique par les outils SAST/SCA/DAST ; exiger zéro erreur de linter sur les branches de release.

Gestion des secrets

  • Aucun secret dans le code source Dart, pubspec.yaml, le code natif ou les journaux.
  • Utiliser des variables d'environnement (par ex. --dart-define) pour l'injection de configuration au moment du build.
  • Expurger les secrets dans les analyses (analytics).
  • Effectuer une rotation périodique des clés/jetons et en cas de suspicion de fuite.

Preuves et traçabilité

  • Archiver les rapports d'analyse, le SBOM, les journaux de build et les notes de version avec chaque artefact.

Scanning automation

  • Intégrer une plateforme SAST/DAST/SCA mobile (prenant en charge Flutter) dans la CI/CD pour qu'elle s'exécute sur chaque PR et pré-release, et faire échouer automatiquement les étapes en cas de problèmes de sévérité élevée/critique.

Phase 1 : Modélisation des menaces, classification des données et inventaire

  • Classifier les données (PII, identifiants, jetons, paiement) et cartographier la collecte, le traitement, le stockage (fichiers, bases de données sécurisées) et la transmission.
  • Identifier les limites de confiance (trust boundaries) : environnement Dart/Isolates, MethodChannels, bibliothèques natives, plugins, API backend.
  • Inventorier les paquets pub.dev tiers ; privilégier les plugins bien maintenus, vérifiés (verified publishers) et respectant le principe de moindre privilège.
  • Minimiser la surface d'attaque des paquets Dart.

Phase 2: Build and configuration hardening

Release settings

  • S'assurer que tous les builds de production sont compilés en mode release (flutter build apk/ios --release) avec AOT activé.
  • Supprimer les endpoints de développement et les indicateurs de fonctionnalités (feature flags) des builds de production.

Android specific

  • Utiliser minifyEnabled true et shrinkResources true dans Gradle.
  • Ne déclarer que les permissions nécessaires dans AndroidManifest.xml.
  • Désactiver le trafic en clair dans networkSecurityConfig.

iOS specific

  • Supprimer les symboles de débogage et le code mort.
  • N'accorder que les entitlements nécessaires.
  • Définir NSAllowsArbitraryLoads = false dans Info.plist.

Phase 3: Local storage and secure storage

Stockage sécurisé

  • Utiliser le plugin flutter_secure_storage (ou équivalent) pour tous les jetons, PII sensibles et clés cryptographiques.
  • Android : S'assurer que le plugin utilise un chiffrement adossé au Keystore (EncryptedSharedPreferences).
  • iOS : S'assurer que le plugin utilise le Keychain avec des paramètres d'accessibilité appropriés (par ex. kSecAttrAccessibleWhenUnlockedThisDeviceOnly).

Files and databases

  • Éviter de stocker des secrets ou des PII sensibles en texte clair dans les SharedPreferences ou dans les fichiers locaux.
  • Chiffrer les bases de données (par ex. sqflite avec SQLCipher) si elles stockent des données sensibles.
  • Ne pas écrire de secrets dans les journaux, même temporairement.

Caches and derived data

  • Éviter de persister des PII dans les caches/répertoires temporaires.
  • Purger les caches/répertoires temporaires lors de la déconnexion.

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

  • Masquer l'UI sensible dans le sélecteur d'applications (par ex. en utilisant le plugin secure_application ou du code natif pour flouter/masquer l'écran).
  • Éviter de lire le presse-papiers au lancement de l'application.
  • Ne jamais placer de mots de passe, clés ou jetons à longue durée de vie dans le presse-papiers du système.

Phase 5: Network security and TLS/pinning

Application stricte de HTTPS/TLS

  • Imposer HTTPS pour toutes les communications de l'application. Le client HTTP par défaut de Dart impose TLS mais doit être configuré pour rejeter les mauvais certificats.
  • Ne jamais contourner les vérifications de certificats en production (badCertificateCallback).

Épinglage de certificat

  • Implémenter l'épinglage de certificat SSL/TLS (par ex. en vérifiant le SHA-256 dans l'objet SecurityContext).
  • Valider la résistance contre les attaques MITM et les scénarios de certificats feuilles (leaf) expirés/renouvelés.
  • Planifier une rotation sécurisée des pins et des options de secours (fallbacks).

Cookies and tokens

  • Éviter les jetons porteurs (bearer tokens) à longue durée de vie sur l'appareil.

Phase 6 : Authentification, autorisation et session

Flux d'authentification

  • Utiliser OAuth2/OIDC avec PKCE pour les flux d'authentification publique (par ex. en utilisant flutter_appauth).
  • Ne jamais intégrer de secrets client (client secrets) ou de clés d'API liées à l'authentification dans le code source Dart.
  • Préférer les composants de navigateur système (Chrome Custom Tabs, SafariViewController) aux WebViews in-app pour l'authentification.

Jetons

  • Utiliser des jetons d'accès (access tokens) à courte durée de vie.
  • Stocker les jetons d'actualisation (refresh tokens) de manière sécurisée (par ex. flutter_secure_storage).
  • Effectuer une rotation et invalider les jetons lors de la déconnexion, d'un changement d'appareil et d'activités suspectes.

Autorisation

  • Imposer l'autorisation côté serveur ; traiter l'état de l'application Flutter comme non approuvé.

  • Utiliser Android App Links et iOS Universal Links au lieu de schémas d'URL personnalisés si possible.
  • Valider toutes les origines et les paramètres des liens entrants au sein du code Dart.

Custom schemes and intents

  • Si des schémas personnalisés sont utilisés, s'assurer d'une validation robuste de toutes les données et types de données entrants.
  • Se défendre contre le détournement d'URL (URL hijacking) et les redirections ouvertes.

Phase 8: Reverse engineering and tamper resilience

Code obfuscation

  • S'assurer que le mode release Flutter compile le Dart en code natif AOT (Android/iOS).
  • Utiliser la prise en charge de l'obfuscation de Flutter (flutter build apk --obfuscate --split-debug-info=/<dir>) pour masquer la logique métier et les noms de classe.

Vérifications de l'environnement

  • Détecter le jailbreak (iOS) et le root (Android) à l'aide de plugins de confiance (par ex. flutter_jailbreak_detection, freerasp).
  • Répondre proportionnellement aux environnements suspects (limitation des fonctionnalités, avertissement ou arrêt).

Anti-tamper

  • S'appuyer sur des contrôles d'intégrité natifs (Play Integrity API pour Android, DeviceCheck/App Attest pour iOS) afin d'assurer l'attestation par le backend.
  • Traiter les vérifications côté client comme des signaux, jamais comme le seul contrôle de sécurité.

Phase 9: Cryptography and randomness

  • Utiliser des implémentations cryptographiques Dart bien examinées (par ex. le paquet crypto ou pointycastle) ou faire appel à des primitives de plateforme natives via MethodChannels.
  • Utiliser le générateur de nombres aléatoires cryptographiquement sécurisé de Dart (Random.secure()).
  • Utiliser des modes modernes (par ex. AES-GCM) pour le chiffrement symétrique.
  • Ne jamais réutiliser d'IV (vecteurs d'initialisation) ou de clés de chiffrement codées en dur.

Phase 10: Permissions, notifications, and identifiers

Privacy‑related permissions

  • Demander les permissions au moment de l'utilisation (point-of-use) avec des explications claires du contexte de l'application.
  • Limiter l'accès aux capteurs de l'appareil (localisation, caméra, micro) à la stricte nécessité.

Identifiers

  • Éviter de lier l'identifiant matériel de l'appareil ; utiliser des identifiants réinitialisables propres à l'application.

Notifications

  • Minimiser les données sensibles dans les payloads de notifications push ; s'appuyer sur la récupération des données au moment de l'ouverture (fetch-on-open).

Phase 11: Logging, analytics, and crash reporting

Hygiène de journalisation

  • Désactiver les journaux de débogage et les print() Dart dans les builds de release (utiliser kReleaseMode / kDebugMode de l'API foundation de Flutter).
  • Expurger les PII et les secrets des événements d'analyse (analytics events) et des rapports de crash (par ex. Firebase Crashlytics, Sentry).
  • S'assurer que les fichiers de mappage d'obfuscation (--split-debug-info) sont conservés côté serveur de manière sécurisée pour la désobfuscation des crashs et ne sont pas expédiés avec l'application.

Phase 12: Testing, DAST, and runtime verification

Interception tests

  • Vérifier la résistance de l'application aux attaques MITM (s'assurer de l'échec de la connexion réseau Dart lorsque des proxy interceptent sans configurations d'approbation spéciales).

Tests d'abus d'API

  • Tester les API backend qui soutiennent l'application Flutter contre l'absence de limitation de débit (rate limiting), l'affectation en masse (mass assignment) et les vulnérabilités d'autorisation (IDOR/BOLA).

Dynamic analysis

  • Exécuter un DAST mobile (qui inspecte le trafic du client HTTP de Dart) pour identifier les API mal configurées et les fuites de données.
  • Exporter les preuves du DAST pour le tri et les retests.

Phase 13: SBOM, and evidence

SBOM et dépendances

  • Surveiller les vulnérabilités des dépendances Dart et des composants natifs (pubspec.yaml, build.gradle, Podfile).
  • Générer un SBOM pour les packages Flutter/Dart.

Paquet de preuves

  • Joindre les artefacts d'analyse (SAST/DAST) au dossier de version (release record).
  • Joindre le SBOM au dossier de version.

Référence rapide pour les praticiens

  • Config: AOT release, kReleaseMode pour masquer les journaux/endpoints. --obfuscate activé.
  • Data: Toujours utiliser flutter_secure_storage ou des ponts de chiffrement natifs ; aucune PII en texte clair dans les prefs/SQflite.
  • Network: Toujours utiliser HTTPS ; épingler les certificats via SecurityContext ; aucun badCertificateCallback de contournement en production.
  • Auth: Utiliser des navigateurs système + PKCE pour OAuth (flutter_appauth). Aucun secret en dur.
  • Tamper: Détection racine/jailbreak (freerasp, etc.), attestation backend (Play Integrity / DeviceCheck).
  • Privacy: Flouter les snapshots d'arrière-plan, vider les données du presse-papiers, demander les permissions juste à temps (JIT).
  • Dart/Flutter: Ne confier au frontend aucune décision d'autorisation (API must verify). Faire appel à des paquets pub.dev approuvés et limités.