Aller au contenu principal

Bouclier de sécurité mobile (OtaSecurityShield)

Le module lib/src/security/ota_security_shield.dart protège l'application mobile contre trois vecteurs d'attaque majeurs avant tout appel réseau ou application de patch OTA :

  1. L'Anti-Repackaging APK (vérification de l'empreinte SHA-256 du certificat de signature de l'APK).
  2. La détection d'appareils compromis (Root sur Android et Jailbreak sur iOS).
  3. Le Certificate Pinning TLS SHA-256 (validation des octets DER du certificat X.509 du serveur OTA).

1. Configuration de la politique (OtaSecurityPolicy)​

La politique de sécurité est définie via la classe OtaSecurityPolicy et passée à TkOtaPush.init(...) :

final ota = TkOtaPush.init(
appReleaseVersion: '1.0.0+3',
securityPolicy: const OtaSecurityPolicy(
// 1. Empreintes SHA-256 autorisées du certificat de signature APK
expectedApkSignaturesSha256: {
'A1:B2:C3:D4:E5:F6:01:02:03:04:05:06:07:08:09:10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26',
},
// 2. Blocage des appareils Rootés / Jailbreakés
blockRootedOrJailbrokenDevices: true,
// 3. Empreintes SHA-256 des certificats TLS serveur (X.509 DER)
pinnedServerCertSha256Fingerprints: {
'42d889f8f4b6bf9d3abb767d3b5f215e0009e4d26cb7b958497e8b291e1b96dc',
},
),
onSecurityViolation: (OtaSecurityVerdict verdict) async {
debugPrint('Violation détectée (${verdict.violationType}) : ${verdict.reason}');
},
);

Normalisation des empreintes SHA-256​

La méthode utilitaire OtaSecurityPolicy.normalizeSha256(String fingerprint) supprime automatiquement les deux-points (:), les tirets (-) et les espaces, puis convertit la chaîne en minuscules :

  • 'A1:B2:C3...' et 'a1b2c3...' sont traités de façon strictement équivalente.

2. Anti-Repackaging APK vs Partage hors-ligne (Xender / ShareIt)​

Sur de nombreux marchés, les utilisateurs partagent le fichier .apk d'une application entre smartphones via des outils pair-à-pair hors-ligne (Xender, ShareIt, Bluetooth).

  • APK officiel partagé via Xender : le fichier APK n'a pas été modifié ; son certificat de signature cryptographique reste celui du keystore officiel de l'éditeur. evaluatePolicy valide l'empreinte et autorise à 100 % les mises à jour OTA.
  • APK pirate décompilé et re-signé : un attaquant qui modifie le bytecode ou les ressources de l'APK doit obligatoirement le re-signer avec sa propre clé privée. L'empreinte SHA-256 observée diverge alors de expectedApkSignaturesSha256 : le SDK bloque immédiatement toute opération OTA avec OtaSecurityViolationType.apkSignatureMismatch.

Fournir la signature APK native à DefaultOtaDeviceIntegrityInspector​

Par défaut, DefaultOtaDeviceIntegrityInspector.readInstalledApkSignatureSha256() :

  1. Appelle le callback apkSignatureProvider s'il a été fourni au constructeur.
  2. Sinon, lit la variable d'environnement Platform.environment['OTA_APK_SIGNATURE_SHA256'].

Pour brancher la lecture native Android (PackageManager.GET_SIGNING_CERTIFICATES via un MethodChannel) :

const platformChannel = MethodChannel('com.monapp/security');

final inspector = DefaultOtaDeviceIntegrityInspector(
apkSignatureProvider: () async {
return await platformChannel.invokeMethod<String>('getApkSignatureSha256');
},
);

final ota = TkOtaPush.init(
appReleaseVersion: '1.0.0+3',
deviceIntegrityInspector: inspector,
securityPolicy: const OtaSecurityPolicy(
expectedApkSignaturesSha256: {'6b6929c8ff345cf008496328d7bff081a8ccfb89498bf9916ed668be3c3dedcf'},
),
);

3. Détection Root (Android) et Jailbreak (iOS)​

Lorsque blockRootedOrJailbrokenDevices: true, DefaultOtaDeviceIntegrityInspector.isDeviceRootedOrJailbroken() vérifie sur Android et iOS (Platform.isAndroid || Platform.isIOS) la présence sur le système de fichiers des chemins compromis suivants :

PlateformeChemins inspectés par défaut (_defaultSuspiciousPaths)
Android (Root)/system/app/Superuser.apk, /sbin/su, /system/bin/su, /system/xbin/su, /data/local/xbin/su, /data/local/bin/su, /system/sd/xbin/su, /sbin/magisk
iOS (Jailbreak)/Applications/Cydia.app, /Library/MobileSubstrate/MobileSubstrate.dylib, /private/var/lib/apt, /private/var/stash

Vous pouvez également injecter votre propre liste de chemins via le paramètre customSuspiciousPaths de DefaultOtaDeviceIntegrityInspector, ou implémenter directement la classe abstraite OtaDeviceIntegrityInspector.

4. Certificate Pinning TLS SHA-256 (OtaCertificatePinner & OtaPinnedHttpOverrides)​

Pour protéger les téléchargements d'assets et les appels HTTPS Dart contre les attaques Man-in-the-Middle (MitM) par certificat racine frauduleux, le SDK fournit OtaCertificatePinner et OtaPinnedHttpOverrides.

Fonctionnement de OtaCertificatePinner​

  • OtaCertificatePinner.computeDerSha256Hex(List<int> derBytes) calcule le condensat SHA-256 hexadécimal (en minuscules) des octets DER bruts (cert.der) du certificat X.509 présenté par le serveur.
  • Si pinnedSha256Fingerprints est vide, verifyCertificateDer retourne true.
  • Si enforcedHosts est renseigné (ex: {'ota.saramoney.com'}), le pinning n'est imposé que sur ces domaines précis ; s'il est vide, il s'applique à tous les hôtes.

Activation globale avec HttpOverrides.global​

import 'dart:io';
import 'package:tk_ota_push/tk_ota_push.dart';

void configureTlsPinning() {
final pinner = OtaCertificatePinner(
pinnedSha256Fingerprints: {
'42d889f8f4b6bf9d3abb767d3b5f215e0009e4d26cb7b958497e8b291e1b96dc',
},
enforcedHosts: {'ota.saramoney.internal'},
);

HttpOverrides.global = OtaPinnedHttpOverrides(pinner);
}

5. Comportements en cas d'échec (OtaSecurityVerdict)​

Lors de l'appel à ota.syncWithRemoteConfig(...), l'évaluation de sécurité s'exécute à l'Étape 0b, avant même d'interroger le RemoteConfigGatekeeper ou le réseau :

Type de violation (OtaSecurityViolationType)CauseComportement du SDK
apkSignatureMismatchSignature SHA-256 de l'APK absente ou absente de expectedApkSignaturesSha256.1. Appelle onSecurityViolation(verdict) si défini.
2. Retourne OtaSyncOutcome avec executionMode: OtaUpdateExecutionMode.blockedBySecurityShield et networkCallPerformed: false.
deviceRootedOrJailbrokenblockRootedOrJailbrokenDevices == true et un binaire/dossier de Root ou Jailbreak est détecté.1. Appelle onSecurityViolation(verdict) si défini.
2. Retourne OtaSyncOutcome avec executionMode: OtaUpdateExecutionMode.blockedBySecurityShield et networkCallPerformed: false.
tlsCertificatePinningMismatchCertificat X.509 serveur rejeté lors de la négociation TLS.La connexion HTTPS échoue immédiatement avant tout transfert de données.