Les chercheurs d’ESET expliquent les détails d’une faille découverte dans VaxiCode Vérif, l’application mobile permettant la vérification des preuves vaccinales québécoise
La sortie d’applications mobiles permettant le stockage et la vérification du passeport vaccinal par le gouvernement du Québec (VaxiCode et VaxiCode Vérif) a fait couler beaucoup d’encre la semaine dernière. C’est avec raison; l’application VaxiCode Vérif sera utilisée par tous les commerçants de services non essentiels dès le 1er septembre 2021.
Comme plusieurs autres, j’ai analysé le contenu du code QR dès que je l’ai reçu lors de mon premier vaccin en mai dernier. La semaine dernière, j’ai aussi analysé les deux applications établies par le gouvernement du Québec et développées par Akinox.
Ce blog explique comment fonctionne le système de passeport vaccinal mis sur pied par le gouvernement du Québec d’un point de vue technique, ainsi que les détails sur la vulnérabilité que nous avons trouvée dans l’application VaxiCode Vérif qui permettait de forcer l’application à reconnaître comme étant valides des codes QR non émis par le gouvernement. À l’heure actuelle, il est impossible de confirmer qu’il s’agit de la même faille trouvée par « Louis » telle que rapportée par Radio-Canada vendredi dernier, puisqu’aucun détail technique n’a encore été publié.
Nous avons nous-mêmes rapporté la vulnérabilité que nous avons trouvée à Akinox dimanche, et nous avons confirmé que la mise à jour de VaxiCode Vérif 1.0.2 pour iOS publiée dans les derniers jours corrige la faille. La version Android des applications n’a pas encore été analysée, mais VaxiCode et VaxiCode Vérif utilisent le cadriciel Expo qui permet de produire des applications iOS et Android en utilisant le même code source. Les applications sur les deux platformes sont donc probablement équivalentes.
Détaillons le contenu du passeport vaccinal québécois
Premièrement, regardons ce que contient le code QR. De façon générale, un code QR inclut exclusivement du texte. Il s’agit souvent d’une adresse URL.
Mais revenons à l’application de passeport vaccinal québécois. On remarque que l’URL contenue dans ce code QR commence par shc:/
. « shc » est un acronyme pour SMART Health Cards, une spécification qui définit un format pour échanger des informations concernant le statut vaccinal d’une personne. Cette spécification a vu le jour en 2021 avec l’objectif de pouvoir délivrer ce fameux passeport vaccinal et de pouvoir vérifier sa véracité. C’est ce même standard qui a été choisi par plusieurs états américains, incluant la Californie, l’état de New York et la Louisiane. Le développement de cette spécification est chapeauté par la Vaccination Credential Initiative, une coalition regroupant des organismes publics et privés dans le but de rendre possible le déploiement sécuritaire du passeport à travers le monde. Akinox, la compagnie qui a développé VaxiCode et VaxiCode Vérif pour le gouvernement du Québec, est membre de cette organisation.
La spécification décrit comment décoder les chiffres dans l’URL en contenu lisible.
L’information est décodée en un JSON Web Token (JWT), ou plus spécifiquement une JSON Web Signature (JWS) puisqu’il s’agit d’un jeton signé. La spécification SHC n’a pas réinventé la roue : JWT est une technologie existante permettant d’échanger des informations chiffrées ou signées numériquement.
Comme cela a été discuté dans les médias, la charge utile du passeport vaccinal contient le nom, la date de naissance ainsi que le lieu et la date de chaque dose de vaccin contre la COVID-19 que la personne a reçue.
Si vous êtes curieux de connaître le contenu de votre passeport vaccinal, il est possible de l’inspecter facilement à partir d’un appareil mobile à l’aide d’un outil en ligne développé par François Proulx.
Pourquoi ne pas chiffrer l’information?
Plusieurs ont émis l’idée de chiffrer l’information dans le code QR. Cela peut sembler à priori comme une bonne façon de la protéger; cependant, il serait alors beaucoup trop facile de déchiffrer ces informations. L’information devant être comprise par VériCode Vérif, l’application devrait donc forcément contenir la clé de déchiffrement. Une fois la clé extraite, n’importe qui pourrait déchiffrer les codes QR. Cela donnerait une fausse impression de sécurité et entrainerait davantage de critiques du public.
C’est pour ces raisons que le protocole SHC ne prévoit pas de méthode de chiffrement. Cependant, il exige une signature numérique.
Comment fonctionne la signature numérique?
La signature numérique repose sur la cryptographie asymétrique, c’est-à-dire qu’une paire de clés est utilisée. Cette paire est composée d’une clé privée, que seulement l’émetteur (ici, le gouvernement du Québec) a en sa possession pour signer des données et d’une clé dite publique permettant de vérifier que la signature a bien été effectuée avec la clé privée.
La cryptographie asymétrique est utilisée, entre autres, pour chiffrer les communications sur Internet. Il n’y a pas d’attaques connues permettant de signer sans avoir la clé privée ou de deviner la clé privée à partir de la clé publique.
Cela veut aussi dire que la priorité est de protéger cette clé privée à tout prix. Compromettre cette clé permettrait de générer des codes QR cryptographiquement valides. Le problème se situait plutôt dans l’implémentation de l’algorithme de vérification dans VaxiCode Vérif.
Quelle était la faille dans VaxiCode Vérif exactement?
La spécification SMART Health Cards a été conçue pour prévoir la possibilité d’avoir plusieurs émetteurs de preuves vaccinales. Ceci reflète bien la réalité: chaque pays ou région est responsable de l’émission de ses propres preuves. Chaque gouvernement dispose donc de sa propre paire de clés permettant de signer et de vérifier les passeports.
La spécification SHC prévoit que l’entité émettrice met à disposition sa ou ses clés publiques sur Internet. La preuve vaccinale contient une URL vers le site web de l’émetteur dans le champ iss
(pour issuer). Une application vérificatrice devrait trouver la ou les clés publiques de l’émetteur en concaténant /.well-known/jwks.json
à cette URL.
Ce que la spécification ne définit pas (pour le moment du moins) est une façon de déterminer si l’émetteur est digne de confiance.
Akinox a choisi d’inclure la clé publique du gouvernement du Québec dans VaxiCode et VaxiCode Vérif. L’application utilise cette clé lorsque l’émetteur est le gouvernement du Québec (plus spécifiquement si iss
est https://covid19.quebec.ca/PreuveVaccinaleApi/issuer
). En revanche, le code permettant de télécharger des clés d’émetteur tiers se trouve quand même dans l’application, malgré le fait que ce ne soit pas nécessaire.
La vulnérabilité réside dans le fait qu’une fois une clé publique téléchargée, elle est utilisée pour valider n’importe quel autre passeport, sans vérifier si elle correspond au contenu du champ de l’émetteur (iss
).
Voici un scénario d’attaque permettant d’afficher une preuve vaccinale forgée comme étant valide :
- Un attaquant génère une paire de clés et rend la clé publique disponible à
https://example.org/.well-known/jwks.json
- Il génère deux SMART Health Card sous la forme de code QR :
- Le premier est créé avec un contenu arbitraire, en autant que l’
iss
soithttps://example.org
. - Le second est créé avec l’information personnelle de la personne qui veut se faire passer comme étant vaccinée ainsi que le champ
iss
pointant vers le domaine légitime du gouvernement, et le signe avec la clé générée à l’étape 1.
- Le premier est créé avec un contenu arbitraire, en autant que l’
- Lors d’une vérification du passeport vaccinal, l’attaquant présente en premier lieu le premier code QR. Cette validation sera rejetée par VaxiCode Verif, mais forcera l’application à télécharger la clé publique de l’attaquant et à l’ajouter à son trousseau de clé de confiance.
- L’attaquant présentera ensuite le second code QR, qui lui sera validée comme légitime par VaxiCode Verif.
La version 1.0.2 disponible depuis dimanche sur l’App Store d’Apple corrige le problème. Cette mise à jour enlève complètement la fonctionnalité de téléchargement de clés publiques à partir de l’URL de l’émetteur.
Aurait-on pu faire mieux?
Les autorités et les développeurs responsables du déploiement de la preuve vaccinal sont soumis à une restriction difficile à mitiger : le temps. L’ensemble du développement et du déploiement de la preuve vaccinale au Québec s’est fait en quelques mois. Même si nous avons pu observer quelques lacunes, le système fonctionne.
Le gouvernement a peut-être manqué une bonne opportunité de publier le code source des applications qu’elle a produites par souci de transparence. Après tout, il n’y a rien à cacher ni rien de secret dans ces applications. La découverte rapide des failles a démontré que l’analyse par un plus grand nombre d’experts améliore la sécurité de ce type d’application. La publication du code source et son analyse par les experts aurait peut-être évité des scandales pouvant affecter la confiance de la population, puisque l’ensemble de celle-ci aurait été à même d’en vérifier la sécurité par elle-même.
Par ailleurs, certains jugent que les données personnelles contenues dans le passeport vaccinal québécois sont excessives. À cet égard, il aurait été possible de faire une version allégée du passeport contenant moins d’information. Ceci dit, cette version allégée pourrait potentiellement être inutilisable à l’extérieur du Québec, puisque les règles pour déterminer si une personne est protégée peuvent changer d’une région à l’autre (quels vaccins sont jugés valables, combien de doses sont requises, etc.).
C’est ce qu’a choisi de faire la Suisse par exemple avec son “certificat COVID light”. Soulignons de plus que le code source des applications suisses est aussi disponible depuis plusieurs mois.
Nous n’avons pas mis à l’épreuve les serveurs permettant l’émission des passeports vaccinaux, parce que nous n’avons ni le mandat ni la permission du gouvernement du Québec ou d’Akinox pour le faire. Contrairement à l’analyse des applications fournies par Québec, ceci constituerait une attaque à un système distant qui pourrait entraîner un risque d’interruption de service.
Conclusion
Notre analyse s’est d’abord penchée sur l’historique du développement de la spécification SHC, développée internationalement spécifiquement pour l’émission de confirmations de vaccination contre la COVID-19. Nous avons par la suite expliqué l’importance de l’utilisation de la cryptographie asymétrique pour la signature des données, et dans le cas présent, pour garantir la validité des preuves de vaccinations fournies. Cependant, nous avons découvert une faille dans l’implémentation de l’algorithme de vérification, qui permettait de forger des preuves vaccinales affichées comme légitimes par VaxiCode Vérif. Nous avons avisé Akinox de cette faille, et elle a été corrigée dès la mise à jour de l’application, soit en quelques jours seulement. Nous avons finalement rappelé les avantages potentiels qu’une plus grande transparence par rapport au code source de ces applications aurait pu représenter.
À la suite de cette analyse, je crois que, bien que VaxiCode Vérif ait connu quelques problèmes à sa sortie, les technologies sur lesquelles repose le système sont solides. L’idée d’utiliser des standards et des technologies existantes est à mon sens une bonne décision. Elle assure à la fois la sécurité de la signature et l’interopérabilité entre régions utilisant le protocole SMART Health Cards.
Le fait que le problème a été corrigé en quelques jours seulement montre que toutes les parties veulent un système sécuritaire. Il y a toujours des pistes d’amélioration, mais l’utilisation de la signature numérique proposée par SHC est, jusqu’à ce jour, sécuritaire.