lucaapp / security-concept

Archived Security Overview for Luca
https://gitlab.com/lucaapp/security-overview
43 stars 8 forks source link

Possible forgery of Check-In QR-Codes #35

Open rmsk2 opened 3 years ago

rmsk2 commented 3 years ago

Overview

Relying only the information contained in this repository it seems to be the case that it is possible for a malicious user to generate a forged check-in QR code in such a way that the forgery is not detectable by the venue or the Luca backend. If I am correct this would allow a malicious user to successfully check into a venue without disclosing any information necessary for contact tracing.

Introduction

https://github.com/lucaapp/security-concept/blob/main/content/processes/guest_app_checkin.md describes the data which is encoded in the QR code generated by the Luca app which is intended to be scanned by the venue:

where

timestamp        = UNIX timestamp rounded down to the last full minute (little endian encoding)
trace_id         = HMAC-SHA256(user_id || timestamp, tracing_secret)  # truncated to 16 bytes
ephemeral_keys   = a new secp256r1 key pair (for DLIES with the daily public key)
dh_key           = ECDH(ephemeral_keys.private, daily_keypair.public)
enc_key          = SHA256(dh_key || 0x01)  # truncated to 16 bytes
iv               = ephemeral_keys.public   # truncated to 16 bytes
enc_data         = AES-128-CTR(userId || data_secret, enc_key, iv)
verification_tag = HMAC-SHA256(timestamp || enc_data, data_authentication_key)

and the tracing_secret, the data_secret and the data_authentication key are neither known by the venue, nor by the attacker nor by the Luca backend. Additionally it is assumed that daily_keypair.public, key_id, version and device_type are public information.

Description of the attack

In order to perform the attack a maliciuous user has to generate a QR code containing the information mentioned above which is accepted by the scanning venue and the Luca backend. So let's have a look at all elements of the QR code:

version

Public information

device_type

Public information

key_id

Public information

timestamp

Public information

trace_id

For an honest user the trace_id is calculated as follows:

HMAC-SHA256(user_id || timestamp, tracing_secret)  # truncated to 16 bytes

The attacker does not know the tracing_secret but neither do the venue nor the Luca backend. This in turn means that any 16 byte random information has to be accepted by the venue and the Luca backend, because they can not verify it.

enc_data

For an honest user this value is calculated as

ephemeral_keys   = a new secp256r1 key pair (for DLIES with the daily public key)
dh_key           = ECDH(ephemeral_keys.private, daily_keypair.public)
enc_key          = SHA256(dh_key || 0x01)  # truncated to 16 bytes
iv               = ephemeral_keys.public   # truncated to 16 bytes
enc_data         = AES-128-CTR(userId || data_secret, enc_key, iv)

It has to be noted that none of the involved parties knows the data_secret but the other information can be generated by the attacker. If the attacker performs the calculations above using a random value (of correct length) for the data_secret and the user_id the results have to be accepted by the backend and the venue because neither of them holds the private daily_key and therefore can not perform the decryption operation which would be necessary in order to detect the forgery.

ephemeral_keys.public

Can be generated by the attacker.

verification_tag

For an honest user this value is caclulated as follows:

verification_tag = HMAC-SHA256(timestamp || enc_data, data_authentication_key)

For this calculation the data_authentication_key is needed. This key is not known to the attacker, the venue and the Luca backend. This again means that any random 8 (the HMAC is truncated to 8 bytes according to this documentation) byte value has to be accepted by the venue as well as the backend because they have no means to verify it.

checksum

Checksum is the SHA-256 hash truncated to 4 bytes of the previously described data and can be easily generated by an attacker.

Conclusion

If I have not missed a central piece of information an attacker can easily create a QR code which can be used to check in to a venue but is unusable for contact tracing and does not disclose the identity of the attacker.

rmsk2 commented 3 years ago

Here it is said that:

In the conventional Check-In process this data would now be encoded into a QR code and presented to a 
Scanner  Frontend to finish up the Check-In and upload it to the Luca Server. Instead, the Guest App re-
encrypts the generated data for the venue keypair, associates it with the scanner ID and uploads the 
finalized Check-In to the Luca Server itself.

The resulting Check-In is equivalent to a Check-In performed by the Scanner Frontend.

If there is no separate authentication process which allows the Luca backend to authenticate a legitimate app installation then the observation made in this issue also applies to a check in where the user scans a QR code provided by the venue.

rmsk2 commented 3 years ago

Given the Security Objectives O1, O2 and O3 it may be impossible to prevent dishonest users from creating fake check ins as described above.

reneme commented 3 years ago

Given the Security Objectives O1, O2 and O3 it may be impossible to prevent dishonest users from creating fake check ins as described above.

Yes, that's exactly the point: If the Luca server were able to verify your identity during check-in (i.e. that you have registered a User ID) it would contradict O2. With a different implementation strategy (i.e. handing out verifiable tokens after registration) multiple check-ins of a single user could be linked (contradicting O3).

Note, however, that it is not possible for such an adversary to generate check-ins in the name of other existing User IDs as they do not possess the user's verification_secret. Hence, the health authority would notice this forgery via the verification_tag.

rmsk2 commented 3 years ago

I understand that there exists a tradeoff between different goals, i.e. your security objectives and the wish to improve the quality of contact tracing Information when compared to the current situation where quite a few people give fake names on contact tracing forms.

Using the approach outlined above anyone who does not wish to be traced can continue to not being traced even when using (or being forced to use) the Luca App.