Intégrité native et blocage des altérations
L'une des promesses fondamentales de TkushPatch est la sécurité d'exécution absolue. Les mises à jour OTA Flutter reposent sur le remplacement à chaud du code Dart compilé en AOT (binaire d'application sous Android, App.framework/App sous iOS).
Cependant, si une modification implique du code natif (bytecode Java/Kotlin, bibliothèques C++, frameworks Swift/Obj-C ou permissions système), un patch OTA provoquerait inévitablement un crash violent (NoSuchMethodError, ClassNotFoundException ou SIGSEGV) chez l'utilisateur, car le binaire natif installé depuis le Store ne contiendrait pas ces nouveaux symboles.
Pour éliminer ce risque, tk-ota-push intègre le NativeIntegrityScanner déterministe (lib/src/cli/native_integrity.dart), validé par test/native_integrity_test.dart.
1. Pourquoi le hash de pubspec.lock ne suffit pas
Historiquement, les systèmes OTA inspectaient uniquement l'empreinte SHA-256 du fichier pubspec.lock. Cette approche présente deux faiblesses critiques :
- Faux-positifs fréquents : La mise à jour d'un package en pur Dart (ex: passage de
intl ^0.18.0à^0.19.0) modifiepubspec.lock, alors que le code est 100 % patchable via OTA. - Faux-négatifs dangereux : La modification manuelle d'un fichier Java/Kotlin dans
android/app/src/main/ou d'un fichier Swift dansios/Runner/ne modifie paspubspec.lock, mais détruit l'intégrité de l'application si elle est patchée.
Le NativeIntegrityScanner de tk-ota-push inspecte donc directement les artefacts binaires compilés.
2. Fonctionnement du NativeIntegrityScanner
Lors d'une commande release, la CLI calcule et enregistre sur le serveur l'empreinte native de référence (native_code_hash). Lors d'un patch, elle re-scanne le nouvel artefact compilé et compare les empreintes.
- Analyse de l'archive : La CLI inspecte le binaire compilé (
.apk,.aabou.ipa). - Vérification du code natif : Le manifeste OS et le code natif sont comparés à la version socle de référence.
- Verdict d'intégrité :
- Si le code natif est intact : La génération du correctif différentiel Dart est validée.
- Si des modifications natives sont détectées : L'opération est refusée avec une consigne claire de soumission sur les stores.
Inspection sous Android (scanAndroidArchive)
Pour chaque fichier de l'APK ou du bundle AAB, le scanner évalue :
| Composant | Fichiers inspectés | Rôle dans l'intégrité |
|---|---|---|
| Bytecode Java / Kotlin | classes.dex, classes2.dex... | Détecte l'ajout ou la modification de code natif Android |
| Manifeste Android | AndroidManifest.xml | Détecte l'ajout de permissions (CAMERA, LOCATION), services ou receivers |
| Bibliothèques C++ natives | lib/<arch>/*.so (ex: libflutter.so, SQLite) | Détecte les mises à jour du moteur Flutter ou de bibliothèques C/C++ tierces |
| Snapshot Dart | lib/<arch>/binaire d'application | EXCLU RIGOUREUSEMENT du hash natif, car c'est le code que l'OTA a vocation à remplacer ! |
| Assets Flutter | assets/flutter_assets/ | EXCLU (traité séparément par le scanner d'assets) |
Inspection sous iOS (scanIosApp)
Sur le bundle Runner.app, le scanner inspecte :
Info.plist: Détecte l'ajout de clés d'autorisation (NSCameraUsageDescription, URL schemes, permissions Bluetooth).Frameworks/: Vérifie l'ensemble des frameworks natifs tiers, en excluant rigoureusementFrameworks/App.framework(qui contient le snapshot Dart).- Binaire principal Mach-O : Calcule le SHA-256 du binaire exécutable natif de l'application.
3. Comportement en cas d'altération détectée
Lors de l'exécution de tk-ota-push patch, si le nativeCodeHash de la version en cours de compilation ne correspond pas exactement à celui de la Release enregistrée sur le serveur :
==================================================================
Vérification de l'intégrité du code natif
==================================================================
Release verrouillée sur Serveur TkushPatch : b7e4a18c...
Patch compilé en local : 8f92cd30...
❌ ERREUR CRITIQUE D'INTÉGRITÉ NATIVE :
Des modifications de code natif ont été détectées entre la Release
de référence et le patch que vous tentez de publier :
- classes.dex : MODIFIÉ (Code Kotlin/Java altéré)
- AndroidManifest.xml : MODIFIÉ (Nouvelle permission android.permission.CAMERA ajoutée)
⚠️ Un patch OTA ne peut PAS modifier le code natif ni les permissions OS.
Si ce patch était distribué, l'application crasherait immédiatement sur les appareils.
ACTION REQUISE : Vous devez publier une NOUVELLE RELEASE Store (ex: 1.0.0+2)
via 'tk-ota-push release' et soumettre l'application à Google Play / App Store.
La CLI stoppe immédiatement l'exécution avec le code de sortie 1 et aucun patch n'est envoyé ni signé sur le serveur.
4. Empreinte du manifeste d'assets (computeAssetsManifestHash)
En complément de l'intégrité du code natif, FlutterProject.computeAssetsManifestHash() calcule de façon déterministe le SHA-256 combiné de tous les assets déclarés dans pubspec.yaml :
declared:assets/images/,assets/i18n/
assets/images/logo.png=8a3f91...
assets/images/promo.png=c2d10e...
assets/i18n/fr.json=5b47a9...
Toute addition, suppression ou altération d'un fichier d'asset produit un hash différent, transmis dans les métadonnées de la Release et du Patch pour validation par le serveur et le SDK OtaAssetManager.
5. Le flag --force (-f) : Quand et comment l'utiliser ?
L'option --force de tk-ota-push patch est conçue pour les cas où le fichier pubspec.lock a différé (ex: mise à jour d'un package Dart pur sans code natif) alors que le nativeCodeHash reste strictement identique :
# Forcer la publication d'un patch dont les dépendances Dart pures ont évolué
tk-ota-push patch 1.0.0+1 -p android --force -m "Mise à jour intl et correctif d'affichage"
Si le NativeIntegrityScanner détecte une véritable modification dans classes.dex, AndroidManifest.xml ou un binaire Mach-O, la CLI refuse catégoriquement la publication, même en présence du flag --force. La sécurité de votre parc mobile prime toujours sur le déploiement immédiat.