Les marchés d'applications alternatifs sur Android : du neuf en perspective ?

Cet article effleure quelques concepts autour des marchés d'applications Android, et leur importance pour garantir la robustesse de l'écosystème. Accrescent est un projet de marché alternatif en développement qui mérite votre attention !

Les marchés d'applications alternatifs sur Android : du neuf en perspective ?

J'ai déjà mentionné à plusieurs reprises sur mon blog des alternatives au Play Store telles que F-Droid et Aurora Store. Le premier est un marché d'applications à part entière destiné à mettre en valeur les logiciels libres, tandis que le second n'est ni plus ni moins qu'un client pour le Play Store permettant aux distributions d'Android sans Play services d'accéder à son catalogue.

Je ne mentionnerai pas l'existence des autres marchés commerciaux (ceux d'Amazon et Huawei notamment) qui sont systématiquement pires que le Play Store pour diverses raisons.

Contexte

Il faut commencer par mentionner Play App Signing. Jusqu'à présent, les applications soumises au Play Store étaient soumises directement par le développeur qui compilait et signait ses propres applications. Depuis le mois d'août 2021, les nouvelles applications mises en ligne sont signées par Google. Je ne pense pas me fourvoyer quand j'imagine qu'à terme, toutes les applications seront éventuellement concernées par ce changement.

Je n'ai jamais hésité à exprimer mes doutes au sujet de F-Droid (je parlerai ici principalement de son dépôt officiel). Selon moi, son modèle consistant en une entité centrale responsable de compiler et signer les applications n'apporte pas de plus-value particulière (si seulement les builds reproductibles étaient mieux développées, peut-être…). Quoiqu'il en soit, la confiance en cette entité ne peut jamais se substituer à la confiance accordée au développeur, puisqu'il n'est pas raisonnable d'attendre de cette entité qu'elle puisse parfaitement analyser le code source de toutes les applications disponibles ainsi que de leurs mises à jour.

Il faut donc d'une part considérer que la confiance au développeur est primordiale, et d'autre part considérer que le modèle de sécurité de son système est le garant de choix pour que ce contrat soit respecté.

Cette situation n'est donc, de mon point de vue, pas idéale. Je souhaiterais à titre personnel ne pas avoir à faire confiance à une partie intermédiaire, d'autant plus que j'utilise une version d'Android où les composants Google ne sont pas privilégiés. Play App Signing n'a pas forcément que des aspects négatifs, mais cela confirme la volonté de mainmise de Google sur l'écosystème Android.

Le modèle de sécurité d'Android

Sur Android, toutes les applications doivent être signées. Cette signature est un moyen cryptographique qui permet de s'assurer de l'authenticité de l'application. Il y a néanmoins un problème logique : il n'est pas possible de s'assurer de l'authenticité lors de l'installation initiale (TOFU = trust on first use). C'est seulement après celle-ci qu'Android épingle la signature et la vérifie à chaque mise à jour (et à travers tous les profils utilisateurs).

GrapheneOS songe à construire une base de données d'empreintes connues pour pallier ce problème.

Chaque application installée par l'utilisateur est régie par un système de permissions, et fonctionne dans son propre bac à sable (son domaine SELinux est explicite : untrusted_app). Si vous ne donnez pas la permission d'accès à des fichiers, à vos contacts, etc. alors l'application ne pourra pas exfiltrer ces données, point. C'est une garantie qui est bien plus robuste que d'analyser le code source (ou par rétro-ingénierie pour les applications sans code source disponible) de manière superficielle et d'espérer pouvoir énumérer l'ensemble des portions de code pouvant exfiltrer vos données, qui peuvent parfois être bien obfusquées.

L'installation initiale est donc une étape critique dans la confiance accordée à l'application et de facto son développeur. C'est pour cela qu'il est systématiquement recommandé de passer par les canaux de distribution officiels de l'application. Il est également souhaitable que ces canaux suivent autant de bonnes pratiques que possible pour protéger ses utilisateurs.

L'importance d'un marché pour l'écosystème

Les marché d'applications "majeurs" ont un rôle important pour l'écosystème des applications Android, et ont un impact direct sur la sécurité et la vie privée des utilisateurs de ce système.

Rapidité des mises à jour

Il est évident que plus les mises à jour sont rapides, mieux c'est. Mais cela peut se heurter aux conditions de soumission qui doivent parfois être vérifiées par le marché en question. Dans le cas du Play Store, il n'est malheureusement pas rare pour un développeur de voir une mise à jour refusée pour des raisons obscures. Quant à F-Droid, l'application peut ne plus être mise à jour pour diverses raisons, ou le processus peut prendre un temps bien plus conséquent que prévu.

La rapidité est un point crucial. Lors d'une divulgation de vulnérabilité, la vulnérabilité en question doit être corrigée le plus rapidement possible. En général, le développeur fait en sorte que les canaux s'organisent pour délivrer la mise à jour le plus rapidement possible et de façon synchronisée. L'ajout de parties et de traitement intermédiaires ralentit forcément ce processus (c'est ce qu'il s'est passé avec la dernière divulgation de vulnérabilité du client Element). Dans le pire des cas, il est même possible que la partie intermédiaire en question introduise des vulnérabilités de manière involontaire (un exemple récent).

Les conditions de soumission

Play Store et F-Droid ont leurs propres conditions de soumission. Le cas du Play Store est intéressant puisqu'il apporte quelques éléments positifs qui devraient, à mon avis, être repris ailleurs :

  • Un certain niveau d'API cible (targetSdkVersion) pour les nouvelles applications soumises, mais aussi les mises à jour. Cela pousse les développeurs à moderniser continuellement leurs applications, et permet aux applications de tirer profite des dernières nouveautés en matière de sécurité et de vie privée.
  • Les permissions particulièrement invasives sont attentivement étudiées et doivent être justifiées. Un exemple de permission concernée est MANAGE_EXTERNAL_STORAGE que nous avons déjà abordé en détails auparavant.

De telles conditions peuvent paraître draconiennes (j'entends déjà M. Cook ricaner), mais elles sont très utiles pour conserver un écosystème sain, évolutif et moderne. J'irai jusqu'à affirmer que ces mesures bénéficient à de nombreuses applications disponibles ailleurs que sur le Play Store, où bien qu'elles ne subissent pas ces conditions directement, elles doivent se plier à celles du Play Store si elles y sont présentes également.

D'autres alternatives ?

Jusqu'à présent, j'ai mentionné Play Store et F-Droid car ces noms reviennent assez souvent. Je n'ai pas mentionné Aurora Store, Aurora Droid, Neo Store, car ce sont des clients qui peuvent régler (ou introduire) des problèmes, sans changer le fond des choses (i.e. la nature même des dépôts d'applications concernés).

Je ne vous déconseille pas l'utilisation du Play Store, bien au contraire. Play Store pose néanmoins des problèmes légitimes, tels que le besoin de créer un compte (Aurora Store ne contourne pas vraiment cette restriction, même s'il peut utiliser des comptes "anonymes"). Je ne déconseille pas non plus F-Droid, même si de mon point de vue ce marché commet délibérément des erreurs fondamentales.

Nous allons tout de même étudier différentes alternatives !

Directement depuis le site du développeur

Il est bien évidemment possible d'installer les applications directement à partir du site web du projet/développeur, ce qui résout notre problème de confiance... ou pas vraiment ? L'avantage d'un client sous forme d'application est que ce client peut drastiquement sécuriser sa connexion aux serveurs qui hébergent les dépôts grâce à des méthodes telles que l'épinglage de certificats qui permettent de prévenir des attaques de l'homme du milieu. Ces dépôts eux-mêmes sont en général signés, ce que le client peut vérifier.

Tandis que lorsque l'on passe par un site web (GitHub par exemple), on fera confiance à l'infrastructure PKI du web (avec tout le joyeux bordel autour), ainsi qu'au serveur web qui peut servir arbitrairement du code ; alors que rappelez-vous, le code d'une application peut au moins avoir son authenticité garantie pour des mises à jour. L'installation initiale d'une application à partir d'un site web implique donc - sur le papier - d'une confiance moindre par rapport à un client-application qui implémenterait les bonnes pratiques.

Signal >> Signal Android APK

Certains développeurs publient pour cette raison les empreintes des certificats utilisés pour la signature de leurs applications. Ce n'est pas pour faire joli : c'est votre devoir de vérifier que l'.apk téléchargée possède la bonne signature. Cependant, ce n'est pas très simple et certainement pas accessible pour le néophyte, car il faut idéalement utiliser l'outil apksigner :

apksigner verify --print-certs --verbose Signal.apk

Exemple de sortie de la commande :

Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): true
Verified using v4 scheme (APK Signature Scheme v4): false
Verified for SourceStamp: false
Number of signers: 1
Signer #1 certificate DN: CN=Whisper Systems, OU=Research and Development, O=Whisper Systems, L=Pittsburgh, ST=PA, C=US
Signer #1 certificate SHA-256 digest: 29f34e5f27f211b424bc5bf9d67162c0eafba2da35af35c16416fc446276ba26
Signer #1 certificate SHA-1 digest: 45989dc9ad8728c2aa9a82fa55503e34a8879374
Signer #1 certificate MD5 digest: d90db364e32fa3a7bda4c290fb65e310
Signer #1 key algorithm: RSA
Signer #1 key size (bits): 1024
Signer #1 public key SHA-256 digest: 75336a3cc9edb64202cd77cd4caa6396a9b5fc3c78c58660313c7098ea248a55
Signer #1 public key SHA-1 digest: b46cbed18d6fbbe42045fdb93f5032c943d80266
Signer #1 public key MD5 digest: 0f9c33bbd45db0218c86ac378067538d

Personnellement, j'aurais préféré que ce soit possible de le voir directement dans l'OS. GrapheneOS projette de travailler sur cela, si ça vous intéresse.

De plus, récupérer l'empreinte depuis le même serveur web qui héberge l'application a un intérêt douteux. Un attaquant peut compromettre ledit serveur, et rien ne l'empêche d'envoyer une application compromise tout en changeant l'empreinte indiquée. Il faudrait idéalement que le développeur offre différentes sources permettant de vérifier cette empreinte.

Quid des mises à jour ?

Un grand avantage des clients classiques est qu'ils proposent des mises à jour automatiques. C'est d'autant plus simple pour les marchés alternatifs depuis Android 12 qui implémente une API permettant de mettre à jour une application sans que l'utilisateur ait à confirmer systématiquement.

Cela ne marche pas sur le client officiel F-Droid car ce dernier cible un niveau d'API trop ancien, donc il faudrait privilégier un client alternatif comme Neo Store ou Droid-ify.

C'est l'API qu'utilise GrapheneOS pour que le Play Store, sans privilèges, puisse conserver cette fonctionnalité (un marché privilégié dispose d'une API puissante et dangereuse permettant déjà de le faire).

Dans le cas d'une application téléchargée depuis un site web, on peut être bien embêté pour savoir quand il y a des mises à jour. Il y a plusieurs cas de figure :

  • L'application peut se mettre à jour elle-même. C'est une situation idéale ! Par exemple Signal et son fork Molly le font, ainsi que Neko pour les amateurs de mangas. Mais ça reste assez rare...
  • Sinon, il va falloir le faire manuellement, et idéalement suivre les flux RSS disponibles. GitHub propose un flux RSS pour les versions : https://github.com/Ashinch/ReadYou/releases.atom serait par exemple le flux pour l'application ReadYou disponible sur GitHub.

Dans la plupart des cas, il va donc  falloir s'armer de son client RSS favori… mais j'ai une solution alternative à vous proposer.

Obtainium

Obtainium est une application open-source qui agit comme un client pour récupérer des applications sur GitHub, GitLab, F-Droid (dépôt officiel ou tiers), etc. Le concept est simple : vous configurez la source pour une application, et Obtainium vérifie régulièrement que cette application est à jour.

Malheureusement l'API à laquelle j'ai fait référence qui permet de mettre à jour sans la confirmation de l'utilisateur n'est pas utilisée puisque l'application est écrite en Flutter, et il n'y a pas de plugin Flutter disponible pour utiliser cette API à l'heure actuelle. Dommage, mais l'idée reste bonne, et l'application demeure néanmoins très utile.

Accrescent : un nouvel espoir ?

Accrescent est un nouveau marché d'applications qui a en son cœur les principes de sécurité et de vie privée que j'ai mentionnés ci-dessus. L'entièreté du projet est bien évidemment open-source avec entre autres un client natif écrit en Kotlin et une console web pour développeurs écrite en Go. Le projet est encore en alpha, mais je suis le projet de très près depuis ses balbutiements.

Logo d'Accrescent : croissant blanc sur fond violet
Logo d'Accrescent

Parenthèse étymologique : accrescent est un mot qui provient du latin, dérivé de accresco/creo (créer, grandir). Le mot est rarement utilisé en français, mais désigne dans la littérature le calice d'une fleur en développement.

Accrescent souhaite utiliser toutes les fonctionnalités modernes d'Android pour proposer un marché d'applications sûr et accessible, que ce soit pour l'utilisateur ou pour le développeur.

La plateforme ne veut pas entraver les développeurs avec des processus superflus, tout en les encourageant à moderniser leurs propres applications avec quelques conditions essentielles. Les développeurs sont donc ici responsables de signer leurs applications, et de les soumettre : Accrescent n'aura aucun rôle là-dedans, en dehors de l'unique validation manuelle lors de la première soumission (et quelques exceptions, cf. ci-dessous).

3 captures d'écran montrant à quoi ressemble le client d'Accrescent à l'heure actuelle
Note : le client est en plein développement

On peut mentionner quelques fonctionnalités, de façon non-exhaustive :

  • Les métadonnées du dépôt sont signées en employant un maximum de bonnes pratiques (avec signify), et sont vérifiées par le client lui-même. Une partie est codée en dur dans le client pour que l'ensemble soit le plus résilient possible à une compromission du serveur.
  • Quand un développeur soumet une application, le hash de la clé publique utilisée pour la signature est ajoutée dans ces métadonnées. Ce hash est toujours vérifié quand vous téléchargez cette application, renforçant ainsi la sécurité de l'installation initiale.
  • La version d'une application est également présente dans ces métadonnées, et Accrescent refusera toute tentative de downgrade. Cela peut empêcher un attaquant de servir délibérément des versions obsolètes et vulnérables.
  • Accrescent supporte l'API d'Android permettant les mises à jour sans confirmation de l'utilisateur, sans privilèges.
  • Accrescent épingle les certificats racines et intermédiaires de Let's Encrypt qui est l'autorité de certification choisie pour délivrer les certificats TLS utilisés par les serveurs du projet. Cela empêche une autorité de certification tierce de pouvoir être utilisée pour délivrer des certificats malicieux pouvant compromettre la sécurité des utilisateurs.
  • Bien que ce ne soit généralement pas le cas, l'ajout de permissions particulièrement invasives (d'après la classification du Play Store) demande une validation manuelle pour s'assurer que l'application n'a pas été compromise et/ou a une utilisation justifiée de cette permission.
  • Les conditions de soumission relatives au niveau de SDK cible sont sensiblement les mêmes que celles du Play Store, à l'exception que les applications ne satisfaisant plus ces conditions seront purement et simplement supprimées car estimées potentiellement dangereuses.
  • Et enfin : les utilisateurs n'ont pas de compte à créer pour l'utiliser !

Accrescent est à l'heure actuelle en alpha publique si vous souhaitez voir un aperçu. Il y a peu d'applications présentes pour l'instant (la console est limitée à des développeurs en liste blanche), mais quand le projet sera suffisamment avancé, de nombreux développeurs devraient rejoindre la plateforme.

Conclusion

La situation est loin d'être idéale et le parfait marché d'applications n'existe pas (encore). Fort heureusement, Android est une plateforme suffisamment ouverte pour que nous puissions voir fleurir des alternatives telles qu'Accrescent. L'objectif de cet article était de fournir quelques informations pour mieux vous éclairer sur votre choix d'utiliser une source d'applications plutôt qu'une autre, et aussi d'offrir une pointe d'optimisme !


Hors-sujet si vous me le permettez : GrapheneOS, un projet qui me tient à cœur comme vous avez pu le voir au travers de mes articles, a été sélectionné par Proton pour sa dernière levée de fonds qui soutient des projets visant à améliorer la sécurité et la vie privé de tous. Vous pouvez donc contribuer à GrapheneOS en participant à cette levée de fonds et en partageant la nouvelle. En plus, il y aura un tirage au sort pour remporter un compte lifetime chez Proton. Plus que quelques jours pour participer !