Conformité mobile : l’éditeur a-t-il encore le contrôle ?
Sur le web, un éditeur sait à peu près ce que son site fait des données. On ouvre l’onglet réseau du navigateur, les requêtes et les cookies sont là, en clair, et un DPO peut les surveiller en continu. Le web est le terrain où le contrôle reste à portée de main.
Le mobile est un autre jeu. Le comportement déclaré et le comportement réel divergent, il n’y a pas d’onglet réseau, le TLS est épinglé, et certains SDK chiffrent leur propre contenu par-dessus le TLS. Un éditeur embarque des dizaines de SDK tiers qu’il n’a pas écrits, et n’a pas grand-chose, nativement, pour voir ce qu’ils font vraiment. Pendant ce temps, la CNIL contrôle les applications mobiles depuis 2025, et c’est l’éditeur qui en répond.
Avant même de savoir si une application est conforme, question qui revient au DPO, il y en a une plus simple : l’éditeur voit-il, et maîtrise-t-il, ce que son application fait une fois que l’utilisateur a refusé ? Pour le rendre concret, on en a mesuré une. On a pris une application d’actualité française parmi les plus installées, lancée sur un téléphone réel ; on a refusé le consentement à l’écran, et mesuré ce qui quitte l’appareil avant et après ce refus. L’application reste anonyme ; les vendors, eux, sont nommés, parce que c’est leur comportement technique qui est observé. Les identifiants et valeurs sensibles sont tronqués.
Méthode et périmètre
La mesure porte sur une session d’environ deux minutes, sur un appareil sous une version récente d’Android. Trois couches d’observation sont combinées. D’abord le trafic réseau, capturé en clair après déchiffrement TLS. Ensuite, une instrumentation au niveau de l’application qui récupère le contenu des requêtes que certains SDK chiffrent eux-mêmes par-dessus le TLS, et qui reste donc invisible à une simple capture réseau. Enfin, la journalisation des accès au terminal : lectures d’identifiants de l’appareil et opérations de lecture ou d’écriture dans le stockage local.
Deux limites à garder en tête. La session est unique, donc les chiffres décrivent un parcours, pas une moyenne. Et la seule source d’identifiant de l’appareil instrumentée ici est l’identifiant publicitaire ; les constats sur la lecture d’identifiants se limitent donc à lui.
Le différentiel en chiffres
La session compte 241 requêtes. 47 partent avant toute interaction avec la bannière, c’est-à-dire avant que l’utilisateur ait fait le moindre choix. 194 partent après le refus explicite.
Avant tout choix, dix familles de vendors sont déjà contactées : Meta, Google, AppLovin, Smart AdServer, Ogury, le SDK d’engagement Batch, le SDK de commentaires Octopus Community, et la plateforme de consentement Didomi. Une partie de la chaîne publicitaire et de mesure s’initialise et émet avant que l’utilisateur ait pu accepter ou refuser quoi que ce soit. Premier signe que le déclenchement n’est pas piloté par le choix.
Après le refus, le trafic ne diminue pas, il augmente.
vendor avant après First-party 10 46 Taboola 0 45 Digiteka / Ultimedia 0 41 Batch (engagement/push) 4 23 Octopus Community 6 13 Meta 9 9 Google 8 9 Smart AdServer 1 3 videoadex 0 3 AppLovin 3 0 Ogury 1 0 Integral Ad Science 0 1 Didomi (CMP) 3 1 Autres (CDN, divers) 2 0 total 47 194
Ce que le refus ne change pas
Refuser n’a coupé aucun de ces flux. Les domaines first-party et la vidéo sont attendus pour une application de presse ; Taboola, Batch, Smart AdServer, videoadex et Integral Ad Science le sont moins après un refus. Le comportement est presque le même des deux côtés de la bannière.
Meta et Google restent actifs au même niveau qu’avant le choix. Taboola monte en charge après le refus, avec quarante-cinq requêtes et, cette fois, sans signal « do not track » systématique. Les écritures dans le stockage du terminal, elles aussi, continuent : une écriture en stockage local, c’est une information inscrite sur l’appareil.
Batch ................. 21 (13 préférences, 8 base de données) Facebook Analytics .... 15 (préférences) Google AdMob .......... 2 (préférences)
Le seul identifiant qui ne fuit pas
L’identifiant publicitaire est lu par l’application, neuf fois sur la session. À chaque lecture, le système renvoie une valeur nulle, avant comme après le choix.
La neutralisation de l’identifiant publicitaire n’est donc pas un effet du refus : c’est un état du terminal, géré au niveau du système et non par la bannière de l’application. Le seul signal de protection qui tient dans cette session est celui que la plateforme impose, pas celui que l’éditeur croit piloter. On note aussi ce qui n’est pas là : aucune requête ne transporte de chaîne de consentement IAB TCF. Le refus n’est pas propagé aux vendors par ce canal standardisé, parce qu’il n’est pas utilisé ici.
14:54:06 source = advertising_id
sdk = com.google.android.gms.ads.identifier
valeur = 00000000-0000-0000-0000-000000000000 (36 caractères, nuls)
via = AdvertisingIdClient$Info.getId(Native Method)Le cas Batch, sous la couche de chiffrement
C’est ici que la question du contrôle devient concrète. Les requêtes vers Batch partent avec un corps illisible au niveau réseau : le SDK chiffre lui-même son contenu, par-dessus le TLS déjà en place. Ses propres en-têtes l’annoncent.
POST /ws/.../tracking X-Batch-Content-Cipher: 2 X-Batch-Accept-Cipher: 2 X-Batch-Nonce: 5389076d-…-ed68e99 Content-Type: application/json <corps chiffré par le SDK, opaque à la capture réseau>
Sous le chiffrement, un identifiant persistant
X-Batch-Content-Cipher: 2 signale un chiffrement applicatif propre au SDK, au-dessus du TLS. Une analyse limitée à la capture réseau s’arrête ici et classe la requête comme non exploitable : la donnée part dans une forme que l’éditeur lui-même ne lit pas avec ses outils habituels. En instrumentant le SDK, on récupère le contenu avant qu’il ne soit emballé. Sur cette session, cinquante-quatre de ces payloads ont été récupérés en clair après le refus.
Une fois lisible, le contenu montre d’abord un identifiant d’installation persistant. Le SDK indique lui-même que l’installation date de huit jours avant la capture : l’identifiant est stable dans le temps et rattachable d’une session à l’autre. À noter, geoip: false, la géolocalisation par IP est désactivée côté SDK.
{
"ids": {
"di": "e68c…fa16", // identifiant d’installation
"fda": "2026-06-10T07:43:47Z", // date de première installation
"bid": "fr.****.****",
"s": "0a1b…acbc", // session
"data_collection": { "geoip": false }
}
}Un profil attaché à cet identifiant
Rattachée au même identifiant, une mise à jour de profil. La première requête à partir après le refus transporte une modification d’abonnements de notification : des segments d’intérêt, attachés à un identifiant persistant, transmis après un refus, dans un canal que l’éditeur ne voit pas sans aller le déchiffrer.
{
"name": "_PROFILE_DATA_CHANGED",
"params": {
"custom_attributes": {
"push_topics.a": {
"$add": ["actu-generale", "infos-du-matin"],
"$remove": ["sport"]
}
}
}
}Ce que la mesure montre
Trois choses ressortent. Une partie des vendors est contactée avant toute interaction avec la bannière. Le volume et les vendors ne diminuent pas après le refus, ils augmentent, et des écritures dans le stockage du terminal continuent. Et un identifiant persistant se voit attacher des segments d’intérêt, après ce même refus, dans un payload rechiffré par le SDK.
Aucun de ces comportements ne se voit avec les outils qui suffisent sur le web. L’éditeur embarque des SDK tiers qu’il n’a pas écrits, il en répond devant le régulateur, mais leur comportement réel ne s’observe pas sans instrumenter l’application en profondeur. Le contrôle suppose la visibilité, et la visibilité n’est pas là par défaut.
On s’arrête au constat. Savoir si ces comportements sont conformes, lesquels relèvent d’une exemption, et comment se partage la responsabilité, ce sont des questions juridiques : elles reviennent à un DPO ou à un conseil, pas à une mesure technique. Ce qui précède n’est pas un avis de conformité, c’est un relevé.
Conclusion
Sur le web, l’éditeur dispose du tableau de bord : il voit ce qui part et peut le surveiller. Sur mobile, le même éditeur reste responsable de ce que son application fait, mais une partie de ce comportement lui est invisible : déclenchement avant tout choix, flux qui ne s’arrêtent pas au refus, et au moins un SDK qui maintient un identifiant persistant et lui attache un profil, le tout sous une couche de chiffrement qu’il faut défaire pour seulement le constater.
La question n’est donc pas seulement « cette application est-elle conforme », mais « l’éditeur a-t-il les moyens de le savoir ». Se donner ces moyens, c’est déjà se préparer à un contrôle. L’écart entre le comportement déclaré et le comportement réel est tout le sujet, et il ne devient mesurable que lorsqu’on descend au bon niveau.