ESET’s cybersecurity expert Marc-Étienne Léveillé analyses in-depth the Quebec’s vaccine proof apps VaxiCode and VaxiCode Verif.
The launch of the mobile applications allowing the storage and verification of the vaccination passport by the Quebec government (VaxiCode and VaxiCode Verif) has caused a lot of ink to flow last week. It is with good reason; the VaxiCode Verif app will be used by all non-essential service merchants as of September 1, 2021.
Like many other experts, I analyzed the contents of the QR code as soon as I received it during my first vaccination last May. Last week, I also analyzed the two applications established by the Quebec government and developed by Akinox.
This blogpost explains how the vaccine passport system set up by the Quebec government works from a technical point of view, as well as details about the vulnerability we found in VaxiCode Verif that allowed the application to be forced to recognize non-government issued QR codes as valid. At this time, it is impossible to confirm that this is the same vulnerability found by “Louis” as reported by Radio-Canada last Friday, since no technical details have yet been released.
We informed Akinox about the vulnerability we found on Sunday, and we have confirmed that the VaxiCode Verif 1.0.2 update for iOS released in the last few days fixes the flaw. The Android version of the apps has not yet been analyzed, but VaxiCode and VaxiCode Verif use the Expo framework that allows iOS and Android apps to be produced using the same source code. Therefore, the applications on both platforms are probably equivalent.
Let’s deep dive in the Quebec vaccine passport’s content
First, let’s look at what the QR code contains. Generally speaking, a QR code includes only text. It is often a URL.
But let’s go back to the Quebec vaccine passport application. We notice that the URL contained in this QR code begins with shc:/. “shc” is actually an acronym for SMART Health Cards, a specification that defines a format for exchanging information about a person’s vaccination status. This specification was born in 2021 with the objective of being able to issue this famous vaccine passport and to be able to verify its veracity. This is the same standard that has been chosen by several American states, including California, New York and Louisiana. The development of this specification is being spearheaded by the Vaccination Credential Initiative, a coalition of public and private organizations working to enable the secure deployment of the passport around the world. Akinox, the company that developed VaxiCode and VaxiCode Verif for the Quebec government, is a member of this organization.
The specification describes how to decode the numbers in the URL into readable content.
The information is decoded into a JSON Web Token (JWT), or more specifically a JSON Web Signature (JWS) since it is a signed token. The SHC specification did not reinvent the wheel: JWT is an existing technology for exchanging encrypted or digitally signed information.
If you would like to know more about the contents of your vaccine passport, you can easily inspected it from a mobile device using an online tool developed by François Proulx.
Should these informations be encrypted?
Many have suggested encrypting the information in the QR code. This may seem like a good way to protect it; however, it would be much too easy to decipher this information. The information must be understood by VeriCode Verif, so the application should contain the decryption key. Once the key is extracted, anyone could decrypt the QR codes. This would give a false impression of security and lead to more criticism from the public.
For these reasons, the SHC protocol does not provide an encryption method. However, it does require a digital signature.
How the digital signature works?
The digital signature is based on asymmetric cryptography, which means that a key pair is used. This pair is composed of a private key, which only the issuer (here, the Government of Quebec) has in its possession to sign data, and a so-called public key, which verifies that the signature has been made with the private key.
Asymmetric cryptography is used, among other things, to encrypt communications on the Internet. There are no known attacks to sign without having the private key or to guess the private key from the public key.
This also means that the priority is to protect this private key at all costs. Compromising this key would allow the generation of cryptographically valid QR codes. This is not the case with the flaw we found: we did not need the private key to forge a vaccine proof that VaxiCode Verif deemed valid. Rather, the problem was in the implementation of the verification algorithm in VaxiCode Verif.
What exactly was the flaw in VaxiCode Verif?
The SMART Health Cards specification was designed to allow for the possibility of multiple vaccine evidence issuers. This reflects the reality that each country or region is responsible for issuing its own evidence. Therefore, each government has its own pair of keys to sign and verify passports.
The SHC specification requires the issuing entity to make its public key(s) available on the Internet. The vaccine proof contains a URL to the issuer’s website in the “iss” (short for issuer) field. A verifying application should find the issuer’s public key(s) by concatenating .well-known/jwks.json to this URL.
The specification does not define (at least for now) a way to determine if the issuer is trustworthy.
Akinox has chosen to include the Quebec government’s public key in VaxiCode and VaxiCode Verif. The application uses this key when the issuer is the Quebec government (specifically if iss is https://covid19.quebec.ca/PreuveVaccinaleApi/issuer). However, the code to download third party issuer keys is still in the application, even though it is not required.
The vulnerability lies in the fact that once a public key is downloaded, it is used to validate any other passport, without checking if it matches the content of the issuer field (iss).
Here is an attack scenario to display a forged vaccine proof as valid:
An attacker generates a key pair and makes the public key available at https://example.org/.well-known/jwks.json
He generates two SMART Health Cards in the form of QR codes:
The first is created with arbitrary content, provided the iss is https://example.org.
The second one is created with the personal information of the person who wants to impersonate as vaccinated as well as the iss field pointing to the legitimate government domain, and signs it with the key generated in step 1.
During a verification of the vaccine passport, the attacker first presents the first QR code. This validation will be rejected by VaxiCode Verif, but will force the application to download the attacker’s public key and add it to its trusted keychain.
The attacker will then present the second QR code, which will be validated as legitimate by VaxiCode Verif.
The version 1.0.2 available since Sunday on the Apple App Store fixes the problem. This update completely removes the functionality of downloading public keys from the issuer’s URL.
What could have been done better?
The authorities and developers responsible for deploying the vaccine proof are under a restriction that is difficult to mitigate: time. The entire development and deployment of proof of vaccination in Quebec was done in a few months. While there have been some shortcomings, the system is working.
Quebec government may have missed a good opportunity to publish the source code of the applications it produced for the sake of transparency. After all, there is nothing to hide and nothing secret about these applications. The rapid discovery of flaws has shown that analysis by a larger number of experts improves the security of this type of application. The publication of the source code and its analysis by experts might have avoided scandals that could affect the public’s confidence, since the whole population would have been able to check the security by itself.
Some people also feel that the personal data contained in the Quebec vaccine passport is excessive. In this regard, it would have been possible to produce a lighter version of the passport containing less information. That said, this lighter version could potentially be unusable outside of Quebec, since the rules for determining whether a person is protected can change from region to region (which vaccines are considered valid, how many doses, etc.).
This is what Switzerland chose with its “COVID light certificate”. It should also be noted that the source code of the Swiss applications has also been available for several months.
We did not test the servers allowing the issuance of vaccine passports, because we have neither the mandate nor the permission from the Quebec government or Akinox to do so. Unlike the analysis of the applications provided by Quebec, this would constitute an attack on a remote system that could result in a risk of service interruption.
Our analysis first looked at the development history of the CHS specification, which was developed internationally specifically for issuing COVID-19 vaccination confirmations. We then explained the importance of using asymmetric cryptography for signing data, and in this case, to ensure the validity of the vaccination proofs provided. However, we discovered a flaw in the implementation of the verification algorithm, which allowed vaccine proofs displayed as legitimate by VaxiCode Verif to be forged. We notified Akinox of this flaw, and it was fixed as soon as the application was updated, which was within a few days. Finally, we pointed out the potential benefits of greater transparency with respect to the source code of these applications.
As a result of this analysis, I believe that, although VaxiCode Verif had some problems at its release, the technologies on which the system is based are solid. The idea of using existing standards and technologies is in my opinion a good decision. It ensures both signature security and interoperability between regions using the SMART Health Cards protocol. In my opinion, a flaw in the system that denied a valid vaccine passport would have a much more serious impact than the reverse, and that is not the case here.
That the problem was fixed in just a few days shows that all parties want a secure system. There are always areas for improvement, but the use of the digital signature proposed by SHC is, to date, secure.