Aller au contenu

Liste de contrôle de sécurité pour application iOS

Phase 0 : Gouvernance, environnement et CI/CD

Appliquer les portes de validation CI (CI gates)

  • Exécuter des analyses statiques sur chaque PR : swiftlint (ou équivalent), tests unitaires/UI, audit des dépendances.
  • Bloquer la version en cas de résultats SAST/SCA/DAST de niveau Élevé/Critique ; zéro erreur de lint sur les branches de version.

Gestion des secrets

  • S'assurer qu'il n'y a aucun secret dans le code source, Info.plist, les storyboards ou les journaux.
  • Utiliser un gestionnaire d'environnement/de secrets pour les secrets.
  • Masquer les secrets dans les analyses (analytics).
  • Effectuer une rotation des clés/jetons périodiquement et en cas de suspicion de fuite.

Preuves et traçabilité

  • Archiver les rapports d'analyse avec chaque artefact.
  • Archiver la SBOM avec chaque artefact.
  • Archiver les journaux de compilation avec chaque artefact.
  • Archiver les notes de version avec chaque artefact.

Automatisation des analyses

  • Intégrer une plateforme SAST/DAST/SCA mobile dans la CI/CD à exécuter sur chaque PR et pré-version (par ex., Ostorlab).
  • Faire échouer automatiquement les portes de validation CI en cas de problèmes de niveau Élevé/Critique provenant des analyses SAST/DAST/SCA.

Phase 1 : Modélisation des menaces (Threat modeling), classification des données et inventaire

  • Classifier les données (PII, informations d'identification, jetons, paiement) et cartographier la collecte, le traitement, le stockage et la transmission.
  • Identifier les limites de confiance (appareil, Keychain/Fichier, URLSession, WebView, canaux de plateforme vers bibliothèques natives).
  • Inventorier les SDK tiers ; privilégier les SDK bien maintenus, signés et respectant le principe du moindre privilège ; minimiser leur nombre.

Phase 2 : Renforcement de la compilation et de la configuration (Xcode + Info.plist)

Paramètres de version Xcode (Release settings)

  • Supprimer les symboles et le code mort (dead code).
  • Activer l'optimisation de module entier (whole-module optimization).
  • Désactiver les indicateurs DEBUG dans les versions de production.
  • Exclure les frameworks de test/débogage de la version de production.
  • Supprimer les points de terminaison de développement et les indicateurs de fonctionnalités (feature flags) de la version de production.

Signature de code et autorisations (entitlements)

  • N'accorder que les autorisations nécessaires (pas d'App Groups, de partage de Keychain, de NFC, de Bluetooth, etc., inutilisés).
  • Utiliser la signature automatique avec des profils de distribution dédiés.
  • Protéger les informations d'identification de signature (par ex., magasin de secrets de la CI, contrôles d'accès).

Sécurité du transport d'application (App Transport Security - ATS)

  • Définir NSAllowsArbitraryLoads = false.
  • Privilégier TLS 1.2+ uniquement.
  • Utiliser des NSExceptionDomains stricts uniquement lorsque cela est nécessaire et dans un délai limité.

Hygiène de Info.plist

  • Désactiver le partage de documents à moins que cela ne soit requis :
  • UIFileSharingEnabled = false
  • LSSupportsOpeningDocumentsInPlace = false
  • Minimiser LSApplicationQueriesSchemes ; privilégier les Universal Links plutôt que les schémas personnalisés.
  • Fournir des chaînes NS[AppData/AppleEvents/SystemAdministration]UsageDescription précises pour toutes les autorisations.

Phase 3 : Stockage local et sécurité du Keychain

Utilisation du Keychain

  • Stocker les jetons/secrets dans le Keychain avec la classe la plus forte possible :
  • kSecAttrAccessibleWhenUnlockedThisDeviceOnly
  • Ou kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly le cas échéant.
  • Contrôler les éléments sensibles avec les indicateurs kSecAccessControl (par ex., biometryCurrentSet, userPresence) lorsque l'UX le permet.
  • Supprimer les éléments du Keychain lors de la déconnexion.
  • Envisager la liaison à l'appareil (device-binding) pour les jetons à haut risque.

Protection des fichiers et bases de données

  • Appliquer la protection des données aux fichiers : NSFileProtectionComplete (attributs par défaut ou par fichier).
  • Chiffrer les bases de données/fichiers sensibles (par ex., SQLCipher ou équivalent).
  • Ne jamais stocker de secrets en texte clair.

Caches et données dérivées

  • Éviter de conserver des PII dans les caches/fichiers temporaires.
  • Purger les données sensibles des caches/fichiers temporaires lors de la déconnexion si besoin.
  • Purger les données sensibles des caches/fichiers temporaires en arrière-plan si besoin.
  • Ne pas écrire de secrets dans UserDefaults.

Phase 4 : Mesures de protection de la confidentialité (UI, presse-papiers, captures d'écran)

  • Masquer l'UI sensible lors de la mise en arrière-plan (flou ou image de remplacement dans sceneWillResignActive / applicationWillResignActive).
  • Détecter la capture d'écran (UIScreen.main.isCaptured) et ajuster le comportement pour les vues hautement sensibles.
  • Éviter de lire le presse-papiers au lancement de l'application.
  • Ne jamais placer de secrets dans UIPasteboard.general.

Phase 5 : Sécurité réseau et TLS/épinglage (pinning)

URLSession/ATS

  • Appliquer HTTPS vers des hôtes de confiance.
  • Rejeter les certificats et les noms d'hôtes invalides.
  • Désactiver les retours (fallbacks) à HTTP.
  • Définir des délais d'attente stricts.
  • Mettre en œuvre des tentatives répétées avec gigue (jitter) le cas échéant.
  • Échouer par défaut (fail closed) en cas d'erreurs TLS.
  • Appliquer l'utilisation de TLS 1.2+ dans les paramètres TLS du serveur.

Épinglage de certificat (Certificate pinning)

  • Privilégier les épingles SPKI SHA-256.
  • Inclure au moins une épingle de secours par hôte.
  • Mettre en œuvre l'épinglage via l'évaluation de confiance de URLSessionDelegate.
  • Valider le comportement face aux tentatives MITM.
  • Valider le comportement avec des certificats feuilles expirés/renouvelés.
  • Planifier une rotation sécurisée des épingles.
  • Inclure une télémétrie sur les échecs d'épinglage.

Cookies et jetons

  • Utiliser des cookies sécurisés, HttpOnly, SameSite pour les flux web.
  • Éviter les jetons porteurs (bearer tokens) de longue durée sur l'appareil.
  • Effacer les cookies et les données web après les sessions sensibles.

Phase 6 : Authentification, autorisation et session

Flux d'authentification

  • Utiliser OAuth2/OIDC avec PKCE pour les clients publics.
  • Ne jamais intégrer de secrets client dans l'application.
  • Privilégier le navigateur système (ASWebAuthenticationSession / SafariViewController) plutôt que WebView pour l'authentification.

Jetons

  • Utiliser des jetons d'accès (access tokens) de courte durée.
  • Stocker les jetons d'actualisation (refresh tokens) dans le Keychain.
  • Effectuer une rotation et invalider les jetons lors de la déconnexion.
  • Effectuer une rotation et invalider les jetons lors d'un changement d'appareil.
  • Lier les sessions au risque de l'appareil (device risk), le cas échéant.
  • Détecter les anomalies (changements géographiques/IP/ASN) et y répondre.

Autorisation

  • Appliquer l'autorisation sur le serveur ; considérer les vérifications côté client comme consultatives.
  • Valider l'absence de vulnérabilités IDOR/BOLA.
  • Valider l'absence de problèmes d'élévation des privilèges.

Phase 7 : Renforcement de WebView (WKWebView)

  • Utiliser WKWebView uniquement lorsque cela est nécessaire.
  • Privilégier les domaines limités à l'application pour l'isolation (WKAppBoundDomains).

Valeurs par défaut

  • Désactiver JavaScript à moins que cela ne soit nécessaire.
  • Désactiver javaScriptCanOpenWindowsAutomatically.
  • Établir une liste d'autorisation de navigation via WKNavigationDelegate.
  • Bloquer les URL file://.
  • Bloquer les URL javascript:.
  • Utiliser un magasin de données non persistant pour les sessions sensibles.
  • Effacer le HTTPCookieStore et les données de site web lors de la déconnexion.
  • S'assurer que Web Inspector est désactivé en production (iOS 16+ isInspectable = false).

Sécurité du contenu

  • Pour le contenu web propriétaire, appliquer la politique CSP.
  • Appliquer HTTPS.
  • Interdire le contenu mixte.

  • Privilégier les Universal Links.
  • Valider les origines et les paramètres des liens entrants.

Si des schémas d'URL personnalisés sont utilisés

  • Choisir un schéma unique.
  • Valider tous les paramètres.
  • Se défendre contre le détournement d'URL.
  • Se défendre contre les redirections ouvertes.
  • Limiter LSApplicationQueriesSchemes aux schémas connus et nécessaires.

Phase 9 : Rétro-ingénierie et résistance à l'altération (tampering)

Réduire les fuites statiques

  • Supprimer les symboles des binaires livrés au magasin.
  • Stocker les dSYMs côté serveur pour la symbolisation des plantages.
  • Supprimer les journaux détaillés dans les versions de production.
  • Supprimer les menus de débogage dans les versions de production.
  • Supprimer les points de terminaison de test dans les versions de production.
  • Supprimer les bascules de fonctionnalités (feature toggles) non destinées à la production.

Vérifications de l'environnement

  • Enregistrer des signaux pour la présence de jailbreak (fichiers, appels système, bibliothèques suspectes).
  • Enregistrer des signaux pour les frameworks de hooking.
  • Enregistrer des signaux pour la présence de débogueurs.
  • Répondre de manière proportionnelle (dégradation/blocage/télémétrie) sans s'appuyer uniquement sur des vérifications côté client.

Tests d'altération (Tamper testing)

  • Valider que les versions reconditionnées échouent aux contrôles d'intégrité ou à l'attestation du serveur.
  • Valider que les versions re-signées échouent aux contrôles d'intégrité ou à l'attestation du serveur.
  • Traiter les vérifications côté client comme des signaux, jamais comme l'unique contrôle de sécurité.

Phase 10 : Cryptographie et caractère aléatoire

  • Utiliser la cryptographie de la plateforme (CryptoKit / CommonCrypto) ; ne pas implémenter de cryptographie personnalisée.
  • Utiliser AES-GCM ou ChaCha20-Poly1305 pour le chiffrement authentifié.
  • Utiliser HKDF/PBKDF2 comme KDF avec un sel approprié et des paramètres adéquats.
  • Générer des clés/IVs avec SecRandomCopyBytes.
  • Ne jamais réutiliser les IV/nonces.
  • Stocker les clés cryptographiques dans le Keychain.

Phase 11 : Autorisations, notifications et identifiants

  • Demander les autorisations minimales requises.
  • Demander les autorisations au moment de l'utilisation.
  • Expliquer clairement la proposition de valeur aux utilisateurs lors de la demande d'autorisations.

ATT (App Tracking Transparency)

  • Demander ATT uniquement si nécessaire.
  • Se dégrader de manière fluide si ATT est refusé.
  • Éviter le fingerprinting et d'autres techniques de suivi interdites similaires.

Identifiants

  • Privilégier identifierForVendor.
  • Éviter IDFA à moins qu'ATT n'ait été accordé.
  • Ne jamais utiliser d'identifiants persistants interdits.

Phase 12 : Journalisation, analyses (analytics) et rapports de plantage

  • Utiliser os_log avec des annotations de confidentialité.
  • Désactiver les journaux détaillés dans les versions de production.
  • Masquer les PII dans les journaux.
  • Masquer les secrets dans les journaux.
  • Masquer les PII et les secrets dans les événements d'analyse.
  • Masquer les PII et les secrets dans les rapports de plantage.
  • Échantillonner et agréger les analyses dans la mesure du possible.
  • S'assurer que la symbolisation des plantages s'effectue côté serveur.
  • Ne jamais inclure de symboles avec l'application.

Phase 13 : Tests, DAST et vérification d'exécution

Tests d'interception du trafic

  • Vérifier la résistance aux MITM avec un certificat invalide.
  • Vérifier la résistance aux MITM avec une non-correspondance de nom d'hôte.
  • Vérifier la résistance aux MITM avec une CA non fiable.
  • Confirmer que l'épinglage (pinning) bloque l'interception là où il est mis en œuvre.

Inspection d'exécution

  • Confirmer qu'aucun secret/PII n'apparaît dans les journaux.
  • Confirmer que les éléments du Keychain sont présents avec les bonnes ACL (Access Control Lists).
  • Confirmer que les fichiers ont NSFileProtectionComplete (ou plus strict si nécessaire).

Tests d'abus d'API

  • Tester la limitation de débit (rate limiting).
  • Tester les protections contre le rejeu (replay protections).
  • Tester les limites de pagination.
  • Tester les vulnérabilités d'affectation massive (mass assignment).
  • Tester les fuites d'erreurs détaillées.

Analyse dynamique

  • Exécuter un DAST mobile tout en parcourant les flux principaux pour mettre en évidence les mauvaises configurations de transport.
  • Utiliser un DAST pour révéler des problèmes d'exécution (par ex., avec Ostorlab).
  • Exporter les preuves pour le tri et les re-tests.

Phase 14 : SBOM et preuves

SBOM et dépendances

  • Générer une SBOM pour le code Swift/Objective-C.
  • Générer une SBOM pour les SDK intégrés.
  • Suivre les CVE affectant les dépendances.
  • Mettre à jour les dépendances régulièrement en fonction du risque.

Dossier de preuves

  • Joindre les artefacts d'analyse à la version.
  • Joindre la SBOM à la version.
  • Joindre les différences (diffs) de Info.plist à la version.
  • Joindre les listes d'autorisations (entitlements) à la version.
  • Joindre les rapports de tests à la version.

Phase 15 : Rapports et alignement sur les normes

Rapport

  • Produire un résumé exécutif.
  • Documenter la portée et la méthodologie.
  • Documenter les conclusions détaillées avec des PoC et des preuves.
  • Attribuer des évaluations de risque aux découvertes.
  • Fournir des conseils de remédiation.
  • Inclure les résultats des re-tests.

Correspondance avec l'OWASP MASVS

  • PLATFORM : Phases 2, 7–8, 11.
  • STORAGE : Phases 3–4.
  • CRYPTO : Phase 10.
  • AUTH : Phase 6.
  • NETWORK : Phase 5.
  • CODE : Phases 2, 9, 12.
  • RESILIENCE : Phase 9.

Référence rapide pour le praticien

  • Info.plist/ATS : Pas de chargements arbitraires ; domaines d'exception stricts ; désactiver le partage de documents/fichiers sauf en cas de besoin.
  • Keychain : Classes ThisDeviceOnly ; biometryCurrentSet/userPresence en option ; supprimer les secrets lors de la déconnexion.
  • Fichiers : NSFileProtectionComplete ; chiffrer les bases de données/fichiers ; éviter UserDefaults pour les secrets.
  • Network : HTTPS uniquement ; épinglage par URLSessionDelegate (SPKI SHA-256 avec sauvegardes) ; vérifier que les tentatives de MITM échouent.
  • Auth : OIDC + PKCE ; jetons de courte durée ; jetons d'actualisation dans le Keychain ; autorisation côté serveur ; tester IDOR/BOLA.
  • WebView : Privilégier le navigateur système pour l'authentification ; si WKWebView, JS désactivé par défaut, liste d'autorisation de navigation, domaines liés à l'application, stockage non persistant pour les flux sensibles.
  • Confidentialité : Masquer les instantanés en arrière-plan ; éviter les secrets dans le presse-papiers ; minimiser les autorisations et maintenir des chaînes d'utilisation précises.
  • Hygiène de la version : Supprimer les symboles dans l'application, garder les dSYMs privés ; supprimer les journaux/menus de débogage ; valider les autorisations (entitlements).

Exemples de configurations et extraits de code

ATS (Info.plist)

  • Configurer NSAppTransportSecurity :
  • NSAllowsArbitraryLoads = false
  • NSExceptionDomains = { yourdomain.com: { NSTemporaryExceptionAllowsInsecureHTTPLoads = false, NSIncludesSubdomains = true, NSTemporaryExceptionMinimumTLSVersion = TLSv1.2 } }

Protection des fichiers (Swift)

  • Utiliser la protection complète des fichiers :
  • try data.write(to: url, options: .completeFileProtection)

Élément du Keychain (extrait Swift)

  • Configurer l'élément du Keychain :
  • kSecClass: kSecClassGenericPassword
  • kSecAttrAccessible: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
  • kSecAttrAccessControl: SecAccessControlCreateWithFlags(..., [.biometryCurrentSet, .userPresence])

Épinglage de URLSession (aperçu)

  • Dans urlSession(_:didReceive:completionHandler:) :
  • Évaluer SecTrust.
  • Extraire le SPKI du certificat.
  • Comparer le SHA-256 du SPKI à une liste d'autorisation d'épingles.
  • Choisir .useCredential ou .cancel de manière appropriée.

Flux de travail allégés

Porte de validation pré-fusion (Pre-merge gate)

  • Exécuter les lints et les tests.
  • Exécuter l'audit des dépendances.
  • Déclencher les analyses SAST/SCA.
  • Bloquer la fusion sur les problèmes Élevés/Critiques.

Staging pré-version (Pre-release staging)

  • Valider Info.plist et les autorisations (entitlements).
  • Construire le binaire de production.
  • Confirmer que les symboles ne sont pas livrés dans l'application.
  • Exécuter un DAST tout en parcourant les flux utilisateurs principaux (par ex., avec Ostorlab) pour valider TLS/épinglage, la protection du stockage et l'hygiène de la journalisation.
  • Corriger les problèmes et retester.

Surveillance post-version (Post-release monitoring)

  • Suivre les plantages et les performances.
  • Effectuer une rotation des clés/jetons selon un calendrier défini.
  • Surveiller les avis de sécurité des SDK et les CVE.
  • Maintenir la SCA pour surveiller les SDK/bibliothèques tiers (par ex., Ostorlab) afin d'alerter sur de nouvelles vulnérabilités.
  • Déclencher des re-tests ciblés lorsque de nouvelles vulnérabilités sont trouvées.