What are the security options for `expo-updates`?

Please provide the following:

  1. SDK Version: 38
  2. Platforms(Android/iOS/web/all): all

I was wondering what options there are to secure the expo-updates process?

Either using Expo’s CDN or expo export and my own CDN results in the JS code being publicly accessible (you’d have to find it first of course), and there does not seem to be a signing or integrity checking mechanism for the update payload.

So if an attacker either gets access to the CDN location, by credentials compromise, dns MITM, ect. the security model of mobile apps is broken.

Apple and Android stores require signed binary apps to ensure they cannot (easily) be tampered with and enforce control over distribution of the app from dev to user device.

Responsibility of securing the signing keys is responsibility of Apple/Android, upload keys need to be secured by developer.

Using expo-updates, though very practically useful, seems to bypass / break this model.

If the above is a correct conclusion, I think a statement should be included in documentation to make this a deliberate choice of the dev.

Hey @aldegoeij - thanks for the question. The way that we conceptualize OTA updates with Expo is by thinking of the clients as more similar to a website than an app. OTA updates for Expo websites utilize HTTPS to provide security, and the same mechanism is used for iOS and Android as well.

You’re right that if someone compromised the CDN server where OTA update bundles are hosted, that attacker could potentially compromise client side apps that utilize that CDN server as well. This would be similar to if someone compromised the credentials of servers for websites like PayPal or Gmail. (Mobile apps do have somewhat greater capabilities than websites but are still subject to the OS-level sandboxing for things like permissions.)

In the future, we would like to implement some stronger security options in the expo-updates client logic, but there are a lot of technical considerations to think about here and we need to identify the threat model that we really care about. For now, if you’re in an environment where you feel like it’s secure to log into a bank account online, that is the level of security that Expo apps with OTA updates have. If you’re in an environment where HTTPS is compromised, you may not want to use Expo’s OTA updates (or, since it’s open source, you’re welcome to modify and write your own security logic).

1 Like

hi @esamelson thanks for the reply & explanation!

I’m not worried about https connectivity to wherever the OTA update packs are hosted, that is industry standard.

I’m worried about the fact that that the OTA update location can be compromised (not the connection) e.g. pushing a malicious updated OTA package to my expo account, which has no 2-factor authentication possibility. Or if I’m using another CDN, that could be compromised (my own responsibility of course)

In addition, there is currently no way that only the mobile app has access to the OTA update location, it is basically world readable, anyone with the url can download the OTA update package and easily inspect the source code of the react app, something that is a lot harder to do when publishing the app through the app store channels.

I would see a more secure OTA mechanism including the following:

  • signing the OTA update packs with a key that is embedded in the published app to ensure that the original developer published the update
    OR even better
  • encrypting the OTA update packages against a key again embedded in the published app so you can push the OTA updates without risking exposing of source code or easy tampering

Hi

I suggest you post a feature request here.

Hey @aldegoeij

We do signing/verification before downloading updates that have been published to Expo’s servers – the key just lives on our server rather than embedded in client applications, which makes it easier to rotate. You’re right that if someone gets access to your Expo account, they could publish a malicious update, but that is difficult to protect against with any sort of signing. We do hope to add 2FA to Expo accounts in the future, and I’ve raised this post internally as part of that discussion. And as you said, you can certainly host updates yourself (or disable them entirely).

It’s true that the OTA update bundles themselves are world readable, but I would like to respectfully push back against your assertion that it’s a lot harder to access source code when publishing the app through app store channels. :slightly_smiling_face: Plain Expo/RN apps without OTA updates simply have the JS bundle embedded into the IPA/APK, which are very easy to unpack (the latter is just a zip file). And if an attacker were to target your app’s OTA updates, they’d need to find the URL to your app on Expo, which would most likely require unpacking an IPA/APK anyway.

In general, any code that is distributed to clients (either through app stores, OTA updates, or any other channels) can be easily decompiled by anyone who knows what they’re doing, and for that reason should always be treated as compromised by default.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.