Software Engineer

Exploring a COVID-19 contact tracing app (STAYAWAY COVID)

To help fight COVID-19, some countries invested in the creation of mobile apps to help detecting transmission of the virus. These apps are based on D3-PT, a system implemented by Google and Apple in a joint effort which was made available on most Android and iOS phones via a software update.

Such contact tracing apps work by indicating their presence to all nearby (participating) devices via Bluetooth and sharing anonymous codes. Once an user is diagnosed with COVID-19, he is able to notify the owners of those devices that they have been physically close to someone infected with the virus in the last 14 days.

Note that, despite the fact that different countries may have different implementations of their contract tracing applications, the backend API is the same and exposure notifications are shared globally, at least across most of the adhering European countries.

Exploring the Portuguese contact tracing app

STAYAWAY COVID is the name of the Portuguese app for contact tracing.

I was curious about exploring the inner workings of the app, so I applied for becoming a beta tester in order to have access to it before its launch.

Access was quickly granted and, after installing and getting to know the application, I decided to decompile its binary and take a look at its code. It is generally fairly easy to decompile an Android application package (.apk). In fact, there are some online decompiler services where you can place the .apk file and download a .zip with the decompiled source code.

I did not spend much time investigating the app, because the truth is that it is not very complex. It serves its purpose well and is not cluttered with unexpected features. In addition to examining the source code of the app, I used Frida together with a proxy to listen for network requests and the fact is that it does not seem to perform any call to external servers except to interface with Google Exposure Notification API, to retrieve app configuration data and whenever an user wants to declare himself as having tested positive for COVID-19.

However, what did call my attention as a potential security flaw was a particular line of the following BuildConfig.java file:

package fct.inesctec.stayaway;

public final class BuildConfig {
    public static final String APPLICATION_ID = "fct.inesctec.stayaway";
    public static final String APP_ID = "fct.inesctec.stayaway";
    public static final String APP_SPECTOR_ANDROID = "android_suppressedABCDEFGHIJKLMNOPQRSTUVWXYZ";
    public static final String APP_SPECTOR_IOS = "ios_suppressedABCDEFGHIJKLMNOPQRSTUVWXYZ";
    public static final String BACKEND_BUCKET_URL = "https://stayaway.incm.pt/";
    public static final String BACKEND_CONFIG_URL = "https://stayaway.incm.pt/";
    public static final String BACKEND_PUBLIC_KEY = "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFQi8rQ3k2QVlxYmZpbERCc3phb3l4WDZHSkZZNQpEY1MvbVU0LzV1Q0FKb1RYbC9kR3FGd1dUV2syR1RIQ2hBYUNweVpBdFo3QjI0YUxHZFRkSkQ5YTdBPT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==";
    public static final String BACKEND_REPORT_URL = "https://stayaway.min-saude.pt/";
    public static final long BUILD_TIME = 1595158050161L;
    public static final String BUILD_TYPE = "release";
    public static final boolean DEBUG = false;
    public static final String DEV_HISTORY = "FALSE";
    public static final String FIREBASE_APP_ID_ANDROID = "1:91383277555:android:f1eeafc72de4f4a3f51486";
    public static final String FIREBASE_APP_ID_IOS = "1:91383277555:ios:c59e8c2306b25dbbf51486";
    public static final String FIREBASE_CLI_TOKEN = "1//lJlHfZI4IACqj7WykMQ0SMJDbniC-PJ2brG3O2Z5tqo3bs-LjkX_gd6mxYvQEyQSvMy03isS2AKCJ56PI8xcaZXnrQlL9sySHs77";
    public static final String FLAVOR = "production";
    public static final String GIT_REPO = "git@gitlab.com:divoc-group/certificates.git";
    public static final String IOS_APPLE_ID = "surppressed@example.com";
    public static final String IOS_TEAM_ID = "H4F6Z9HC74";
    public static final String IOS_TEAM_NAME = "Suppressed Name";
    public static final String IS_RELEASE = "TRUE";
    public static final String IS_UI = "FALSE";
    public static final String NAME = "production_release";
    public static final int VERSION_CODE = 61;
    public static final String VERSION_NAME = "0.2.2";
}

The file BuildConfig.java holds a class automatically generated by the Gradle build tool so that the app code can inspect information about the build.

One of the variables defined in this file is called FIREBASE_CLI_TOKEN, meaning that it holds an access token to Firebase services. This token can be used with the Firebase Command Line Interface (CLI) Tools to test, manage and deploy a Firebase project from the command line. This includes being able to:

  • Deploy code an assets to Firebase projects

  • Interact with data in a Firebase database

  • Import/Export users into/from Firebase

At first sight this seemed dangerous. This particular token provided access to some Firebase projects from Keyruptive (one of the companies responsible for developing STAYAWAY COVID) as well as to a Firebase project named STAYAWAY COVID. Could it be that this token allowed a malicious user to access and alter the backend services that support this application? For example, changing the app configuration for all users and setting a very low alerting threshold, so that everyone thinks they are likely to be infected and therefore causing a massive spike in requests for COVID-19 testing?

No, that was not the case. Having established contact with the app developers about this issue I was informed that Firebase was not being used in any backend component. It was only used to help distributing test versions of the app rather than as a data repository. Nevertheless, having a Firebase access token exposed to the public is still a security flaw which could allow access to read or alter potentially sensitive data in any of the 5 Firebase projects it gave access to.

The issue was promptly resolved the day after my report. The token was invalidated and new tokens are no longer being mistakenly bundled in the Android Application Package file.

I find it important to have multiple pairs of eyes reviewing software, especially in the case of contact tracing apps where its success depends on having a large userbase and where privacy concerns are a big topic. In my investigation, the security issue I found did not have any impact on the STAYAWAY COVID app itself, however different code reviewers may always find other concerns. On very positive news, the source code of the application is now available, so security researchers or generally curious people can freely analyze it.