"Private" Project is not Private


We are setting up expo to use for builds and development for android and ios. We made sure to check the “private” option on the project page. However, in an incognito browser if we enter in the following:

https://expo.io/@[USERNAME]/projects/[PROJECT NAME]

…the project still shows up and on Android there is a QR code to download and install the app! This seems like a big security issue. Is there a way to make the app truly private?


As described when you select public/private

Making your project public will allow anyone to see your project on your profile.

and that is the only difference, url you mentioned needs to be always public for OTA updates to work

Thanks for the reply. That is a serious problem! At least during development it should be possible. We just wanted to build the apps on Expo and then handle distribution ourselves but it looks like that will not be possible. We’ll have to look at another solution. Thanks again.

additionally - you can use the "privacy": "hidden" configuration in your app.json to hide the project page

Thank you, I appreciate the info about self-hosting. Regarding privacy: ‘hidden’, my assumption was that that was the same as toggling “Private” on the project page in the UI, which I had already done.

the web ui needs to be updated - “private” in the web ui maps to “unlisted” - which means people can only access it if they happen to know the url. “hidden” means it cannot be accessed except by authorized users (you, your team/org)

Ah, that is entirely different! Based on the comment above by wkozyra, if it’s private the only difference is it won’t show up on your profile. But you’re saying if it’s ‘hidden’ it will require authentication?

Based on the comment above by wkozyra, if it’s private the only difference is it won’t show up on your profile

For private meaning unlisted that it’s correct, for hidden it’s not, but regardless of that I’m not really sure why it changes anything, the only thing that is “private” in that case is a website page, an actual endpoint for OTA updates is still public (because it has to be for any device to download updates) and on that endpoint, you can access the same info that website would display.

Self-hosting your js bundle also does not change much, because any user that can install your app can just unzip apk or ipa and get access to that code. This is not anything specific to expo, the same problem exists for react-native or native Android/iOS apps (although it’s harder to do with native code than with js) or any client-side application.

The only case where the above does not apply is when you consider all devices it will be installed on as “trusted”. In that case if you want to have true private app you would need to:

  • use turtle-cli instead of cloud builds http://github.com/expo/turtle-cli
  • self-host on localhost on the machine or CI job where you run turtle-cli build
  • disable OTA updates
    but by choosing this approach you are losing a lot of benefits that Expo provides
1 Like

It may not seem like a big difference, but a short URL like the one in my first post can be easily discovered. Note that this is not just about keeping the code safe. Sometimes an entire project must be private during development such that no one can see or download it (and I think that is a reasonable expectation). I don’t know what the URL is like for the OTA updates, but I imagine it’s much longer (with some kind of hash) and essentially equivalent to being password protected for that reason.

Disabling the OTA updates actually looks like a good solution for us. We’re distributing the app through AppCenter during development, and so we just need Expo for creating the builds and for the development environment, which it is really good at.

Does this mean that I just add “updates.enabled: false” and "privacy: “hidden” to my app.json, and then it will no longer be publicly accessible?


it depends how you define “publicly accessible” - the code will be uploaded to expo servers and if someone can guess your username and app slug they can find it. the expo.io/@yourusername/yourapp page won’t be available to the public, though. so it’s publicly accessible just like how if you press “share” on a google doc or dropbox file and copy a link that anyone can access, anyone can technically read it - but they need to know the url.

Thanks for the reply. Unfortunately this is not going to work. There’s a big difference between this and a Google doc share with a copy link. With link sharing on a typical platform like Google or OneDrive, the link looks something like this: j47fgdkvbvt4zzjd827tgff, which essentially password protects it. And on OneDrive, which is what I normally use, you can also set a password on the link so it’s really quite secure.

Just a suggestion: it seems like there really should be a permissions page where you can open and close these access points based on your needs. I’m sure many companies using Expo are developing apps for clients and it seems a bit strange to me that there isn’t some basic security in place.

But I appreciate the prompt responses!

We are not saying that we couldn’t do that, in my previous comment I wanted to show that security measures like that would be pointless, because whatever we put in url can be easily extracted from apk or ipa, so why even bother. This way we at least have clean human readable urls

I understand that you don’t like the fact that this stuff is accessible under simple to guess url, but this behavior is in no way a security issue. Everything that is public in expo apps needs to be public, it’s not sth expo specific, it’s fundamental to all client side applications.

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