Un assetlinks.json placeholder en prod, et vos deeplinks sont interceptables
La vérification App Links échoue en silence quand le fichier est un exemple copié-collé. Résultat, vos liens deviennent interceptables. Détectable en une commande.
Le fichier est en ligne, l'app s'installe, les liens s'ouvrent. Tout a l'air de marcher. Et pourtant : la vérification App Links a échoué en silence, et n'importe quelle app peut intercepter vos liens.

C'est une erreur que je croise régulièrement en audit, et elle a une particularité : elle ne produit aucun symptôme visible pour l'équipe.
Le mécanisme
Sur Android, les App Links reposent sur une preuve de propriété du domaine. L'intent-filter déclare android:autoVerify="true", et à l'installation, le système va chercher https://votre-domaine.com/.well-known/assetlinks.json. Ce fichier doit lister le package name de l'app et l'empreinte SHA-256 de son certificat de signature.
Si tout correspond, vos liens https://votre-domaine.com/... ouvrent directement votre app, sans passer par un sélecteur.
Le problème : ce fichier est souvent copié depuis la doc ou un template de CI, avec le package d'exemple ou l'empreinte du keystore de debug. Et là :
- Aucune erreur au build. Le fichier n'est pas validé côté compilation.
- Aucun crash à l'exécution. L'app fonctionne normalement.
- La vérification échoue en silence à l'installation. Le système note simplement le domaine comme non vérifié.
Pourquoi c'est un problème de sécurité, pas juste d'UX
Sans vérification, vos liens https retombent au rang de deeplinks classiques : n'importe quelle app installée peut déclarer le même pattern d'URL et apparaître dans le sélecteur, voire capter le lien directement selon les versions d'Android.
Déroulez le scénario avec les liens que les apps envoient réellement : magic links de connexion, liens de réinitialisation de mot de passe, callbacks OAuth. Une app malveillante installée sur le device peut se positionner sur ces URLs. La vérification App Links est précisément le mécanisme qui l'en empêche, et c'est lui qui est cassé par le placeholder.
Détectable en une commande
Côté device :
adb shell pm get-app-links votre.package.name
# → "verified" ou "none" domaine par domaine
Côté serveur, comparez ce que le fichier déclare avec la vraie empreinte de signature :
curl -s https://votre-domaine.com/.well-known/assetlinks.json
# vs l'empreinte réelle du certificat de prod :
keytool -printcert -jarfile app-release.apk | grep SHA256
Si l'empreinte du fichier ne correspond pas à celle du certificat (ou si le package name est encore com.example.app), vous avez trouvé le bug. Cette comparaison fait partie de ma checklist d'audit systématique, parce qu'en années de pratique, je n'ai presque jamais vu une équipe la faire d'elle-même : le fichier « marche » depuis le premier jour, personne n'y retouche.
iOS a exactement le même mécanisme avec apple-app-site-association, et exactement le même mode de défaillance silencieux.
À retenir
- Un
assetlinks.jsond'exemple passe tous les builds et tous les tests fonctionnels : l'échec de vérification est invisible. - Sans vérification, vos liens sensibles (auth, reset, OAuth) sont interceptables par une autre app du device.
adb shell pm get-app-links+ comparaison d'empreinte : deux commandes, dix secondes, à mettre dans votre checklist de release.
Quand avez-vous vérifié le contenu réel de votre assetlinks.json pour la dernière fois ?