Ma première CVE ! (et probablement la dernière…)
Depuis cet été je me suis découvert une nouvelle passion : le paramétrage de la localisation sur les terminaux Android. Ce n’est pas commun comme hobby… mais j’y ai tout de même consacré pas mal de temps et ai rédigé quelques billets dessus. Dans celui-ci, je raconte comment, avec beaucoup de chance et un peu d’obstination, j’ai trouvé ma première vulnérabilité !
Tout à commencé cet été par un article du NYTimes où des développeurs d’applications de contact tracing s’indignaient : pour utiliser l’API Exposure Notification (l’API proposée par Apple et Google) sur Android, il fallait activer la localisation alors que, justement, ces apps ne localisaient pas. On pouvait y lire une réaction de Google qui expliquait que c’était pour protéger la vie privée des utilisateurs, position que Google réitérait quelques jours plus tard dans un billet de blog. A la lecture de ces articles, j’étais perplexe, je pensais que ces apps étaient obligées de demander la permission de localiser pour scanner avec le Bluetooth Low Energey (ce qui est pertinent car le BLE peut être utilisé pour localiser) et j’ai dû m’y reprendre à plusieurs fois pour comprendre que le problème était différent : en fait il fallait activer le GPS sur le téléphone pour pouvoir utiliser le BLE (je ne comprends toujours pas le raisonnement derrière, mais ça c’est un autre sujet).
Une fois que j’ai compris ce dont il s’agissait, j’ai été assez surpris par cette découverte. De mon côté, ça faisait plusieurs mois que j’utilisais StopCovid sur Android sans que l’application ne m’ait demandé d’activer le GPS. Or StopCovid utilise elle aussi le BLE pour détecter les appareils à proximité. A en croire la déclaration de Google sur la nécessité d’activer la localisation pour scanner le BLE, StopCovid ne pouvait pas fonctionner correctement sur mon appareil si je n’activais pas la localisation. A priori, Google connaît son OS… donc il devait forcément y avoir un bug dans StopCovid.
J’ai donc alerté l’équipe de développement de StopCovid (ainsi que celle de TraceTogether) de ma découverte en indiquant que l’app dysfonctionnait probablement sur les tels Android qui n’avaient pas le GPS actif. Ils ont fait quelques tests qui ne se sont pas avérés concluant…
Crier au loup?
De mon côté, assez sûr du fait que j’avais trouvé un bug, j’ai essayé de faire des tests, mais la difficulté c’est que le bug n’affecte que le scan (i.e. la possibilité d’écouter les trames à proximité), difficile donc d’observer si ça fonctionne ou non. N’ayant pas l’habitude de développer sur Android, j’ai un peu peiné à trouver comment débugger StopCovid (depuis, je me suis rendu compte qu’il existait un fork qui simplifiait les choses). Au final j’ai réussi mais je n’ai pu que constater que l’app fonctionnait bien lors de plusieurs tests, même avec la loc désactivée1.
La fragmentation d’Android en cause?
Persuadé que Google disait vrai, mais forcé de constater que StopCovid ne buggait pas, j’ai essayé de trouver ce qui pouvait expliquer ce « dé-dysfonctionnement ». Apparemment je n’étais pas le seul à m’être intéressé au lien BLE/localisation et j’ai donc essayé de creuser les articles que je trouvais. La fragmentation d’Android semblait être une des causes, j’ai creusé un peu et ai demandé à quelques connaissances de tester et, effectivement, il semblait que dans certains cas ça pouvait dysfonctionner. J’ai essayé de documenter le problème, en lisant des bouts du code Android j’ai trouvé qu’un paramètre (appelé “strict_location_check”) existait pour permettre à certains téléphones de ne pas avoir à activer la loc pour scanner le BLE. Ce qui a donné lieu à un premier billet sur le sujet !
Ça n’explique pas tout
Je ne suis expert ni en Bluetooth, ni en développement Android mais à la lécture du coude source d’Android, je notais que quelque chose clochait : sur la version d’Android qui tournait sur mon téléphone (Android 10), le paramètre “strict_location_check” n’était plus utilisé d’après le code source. Si StopCovid fonctionnait sur mon appareil alors que la loc était désactivée, ce devait être pour une autre raison…
En creusant un peu et en échangeant sur Twitter, je me suis rendu-compte que les scans effectués par StopCovid contournaient la vérification de la localisation car il s’agissait de « batch scans » et qu’ils passaient donc par un circuit de vérification différent. J’avais enfin mon explication et j’avais même un mini-arbre de décision pour expliquer dans quel cas il fallait activer la localisation pour pouvoir scanner le BLE.
« Wait a minute! it’s not what it looks like… it’s worse! ».
Mais l’histoire ne s’arrête pas là, je venais de trouver une petite faille. Pour reprendre les propos de Kimberley dans Melrose Place, « it’s not what it looks like… it’s worse! ».
Les applications qui utilisent BatchScan ne contournaient pas seulement la partie du code qui vérifie que la localisation est active (la vérification qui me semble illogique et injustifiée), elles contournent aussi la partie du code qui vérifie que l’application a bien obtenu la permission de localiser. C’est-à-dire que des applications auraient pu utiliser des balises/beacons bluetooth pour traquer la localisation des utilisateurs sans leur en demander la permission .Ce second aspect est beaucoup plus problématique et justifiait d’informer Google de cette découverte afin qu’ils corrigent le problème (au passage je vais probablement empocher une récompense de la part de Google :).
Sur le coup, j’étais super fier : la dernière fois que j’avais trouvé une « vulnérabilité » dans un produit Google, c’était il y a 10 ans, et je n’avais eu qu’une « mention honorable »… Bon, après, j’ai rapidement déchanté en réalisant que certains trouvent plusieurs vulnérabilités par mois.
Épilogue
Le problème a été corrigé dans le bulletin de février (CVE-2021-0328), mais le correctif ne se contente pas de forcer les applications qui scannent le BLE à obtenir la permission de localiser, il les force aussi à demander l’activation de la localisation, ce qui est au final assez négatif. Maintenant, il va falloir prochainement activer la localisation pour utiliser StopCovid/TousAntiCovid, du moins sur les nouvelles versions d’Android … et je reste persuadé que cette deuxième contrainte est mauvaise et qu’il aurait été préférable que Google ne corrige que le vrai problème.
Avec Mathieu Cunche, nous avons commencé à documenter la faille, à « l’optimiser » et à voir comment elle pourrait être utilisée en pratique. Nous rédigeons d’ailleurs un papier sur le sujet !
Vincent Toubiana (@vtoubiana)
1Pour l’anecdote, j’ai fait le test en conditions réelles quelques semaines plus tard : quand je me suis déclaré positif sur l’appli, ma moitié a bien été notifiée.