Firestore security rules to control access only from an app [duplicate] - ios

This question already has answers here:
Locking down Firebase DB access to specific apps
(2 answers)
how to make sure only my own website (clientside code) can talk to Firebase backend?
(1 answer)
Closed last month.
I have a messaging app that uses firestore storage to store all attachments and realtime for all messages. I find myself with the problem that by default any user from the Internet can read data, in the case of storage, knowing the url, you access the file and in the case of realtime, the messages.
My idea is to propose two options to see which is viable:
I have an app registered as a project, can the rules be configured to only allow requests that come from that app? How would these rules be made in store and realtime?
It can be configured so that only users registered through the Authentication section have access to the storage and realtime information.
For this option two I have tried this rule:
allow read, write, delete: if request.auth != null;
But I can still consult the resource from the internet and the browser without obviously being a registered user in my app.

You can't configure the security rules to only allow access from your own application, but nowadays you can configure App Check to do precisely that and can be applied to both Cloud Firestore and Cloud Storage.
App Check is not a guarantee though, so you'll still want to implement your security rules so that they only allow valid operations. How to do that is pure business logic of your application, so only you can determine how to implement - similar to how you implemented that business logic in the source code of your iOS app.
Also see:
Is it safe to expose Firebase apiKey to the public?
Locking down Firebase DB access to specific apps

Related

Firebase Database - Can the creator read & write with it being false?

I was wondering if the creator of the database could read and write regardless of it being both set to false?
{
"rules": {
".read": false,
".write": false
}
}
And if it is so that no one can read and write including the creator, how do I make it so that I can be the only one to read and write?
With security rules like the ones you're showing, all direct access from mobile and web clients is fully rejected, regardless of how the user is authenticated in your app.
However, all backend SDKs, especially the Firebase Admin SDK, that are initialized with a service account will always bypass security rules. This means that code running in Cloud Functions, for example, will not be affected. This account is not necessarily the "creator" of the database - it is just a Cloud IAM account that's added to the project.
The Firebase console also bypasses security rules.
This means you can write backend services and API endpoints that work with the database on the end user's behalf, without granting them any direct access to the data.
If you want only one specific user, Authenticated by Firebase, to be able to read and write the data from a web or mobile app, you will have to code that into your security rules using the given UID of the account.

Firebase security and hash

I have an iOS app and I'm using Firebase as my database.
I know a little about Firebase rules for saving data but i don't have users in my app so i just want to know -
Does Firebase encrypt or hash or secure the transaction between my app and the database?
I don't want some hacker to just easily intercept my call to Firebase and change something and my database will be updated with the wrong information.
Anybody knows the answer to that or how to do that if Firebase doesn't do it automatically?
Thank you
Traffic between your app and the Firebase database always goes over HTTPS, so in general is quite well secured.
But if you don't use authentication and security rules in your app, all a malicious user has to know is the URL of your database (https://yourapp.firebaseio.com) to be able to wreak havoc. This is the nature of a cloud-hosted service: since every client needs to have access to the service, you have to assume malicious users will also have access to the service.
For more on this, see:
How to prevent other access to my firebase
How to make firebase storage only available to users of the app
Swift: Firebase: How to ensure no one can access my db except my app

"Copy this file to your authentication server" - Firebase Custom auth

My goal is to prevent users of multiple login in. I do not want this to be client-side, with like the onDisconnect and onConnect values, but with a server check. I came across this answer:
How to prevent simultaneous logins of the same user with Firebase?
Which tells me to create a custom auth system. When I am following the docs (https://firebase.google.com/docs/auth/ios/custom-auth) I need to "Copy this file to your authentication server" (3c). How would I do this? I am just using Firebase and my little iOS app. I would like to manage everything on these 2 things, no server in between, is this possible? Or can this file only be uploaded through another server?
If above things are not possible, how can I server check if the user really signed in? I am using Cloud Functions, but I did not came across a trigger for a user signing in. Please no answers with onDisconnect/onConnect, I want it server side. A user may NOT login if he is already logged in. Thanks :)
Implementing custom authentication requires that you have a secure place to mint the custom token that identifies each of your users. You cannot do this securely with only client-side code, because that would mean everyone could claim to be whoever they want.
While you can use Cloud Functions for Firebase to implement a secure back-end without spinning up your own server, I highly recommend against doing that just for the purpose of preventing a user to sign in from multiple locations.
It's important when talking about security to split these two steps:
Authentication - a user proving to be who they are
Authorization - the authenticated user being able to use your app
There very seldom is a reason to keep a user from proving who they are. Your concern seems to fall onto keeping them from using the app from multiple locations. To do that, it's probably easier to track for each user where they are using the app from already using Firebase Database's presence system.
Also see:
How to handle multiple connections of the same user on Firebase?
Android - How to detect same user from multiple devices?
How to prevent same user logging in from different devices ? My app is paid , so I dont want credentials to be shared

How to securely store AWS service ids for iOS?

I'm developing an iOS app that uses Cognito User Pools / Federated Identities, Mobile Analytics, and S3 to manage various features of the app, and recently I have become concerned for the security of these features. I already use IAM roles to control the services unauthenticated vs authenticated users have access to, but most of these services use strings (e.g. user pool app client id or user pool app client secret for User Pools, or app id for Mobile Analytics) to give the app access to that service.
What are the best practices to securely store these strings on the device to be used when necessary? Is it even necessary to secure these strings since the app is using IAM roles?
If it is necessary to securely store the strings, I have read that using the CommonCrypto library to encrypt strings before putting them in the keychain is best, but I'm not sure what key to use for encryption since my user needs unauthenticated access to those services. Any advice would be tremendously helpful.
This is a common problem to any mobile app. If someone really wants to, it's not difficult to decompile the app and scrape the keys from it. It's great that you are using IAM roles to restrict feature usage. This will limit the blast radius of attackers, but not necessarily prevent them.
Wth user pools you also get a globally unique identifier which can be used with IAM to restrict what S3 you can use key pre-fixes (which act similar to folders) to limit the objects that users can access to pre-fixes with their unique identifier. You can refer to https://mobile.awsblog.com/post/Tx1OSMBRHZVM9V0/Understanding-Amazon-Cognito-Authentication-Part-3-Roles-and-Policies (Using user pools as the provider, which will use the identity id as the prefix). Depending on how you structure your app you could use this so each user can only modify their own objects. I don't think Analytics has any way of restricting like this... because it wouldn't really make sense for it.
As far as securing your ID's there are things you can do to help mitigate, but there is no fool proof way to prevent someone taking it. You could for instance have the app make a call to your server for the ID... but then an attacker could just call the server. You could encrypt it, which might make it more difficult for an attacker to get, but you have to keep the key somewhere and if the app could get it so could someone who decompiles the app. Unless your app users get some sort of password from outside the app and put it in there isn't a complete way to lock it against attackers.
Hope this helps.

Secure cloud functions in Parse from iOS

TLDR: All I want to do is secure my cloud function in Parse so that it only accepts requests from my iOS app. How can I do that?
Longer version:
I recently got started with using Parse for a client side app I'm building using a Google API.
Before using Parse, my issue was that the Google API calls from my app were not secure. I tried a Man in the middle attack on my app, and I was able to successfully get the bundle id and app id (Google claims some form of security is achieved by ensuring that the call is from the correct bundle id that you can specify on their console). So despite using SSL, seems like it was easy to get this information. Now this Google API is paid, so someone could easily abuse my key when I release my app and raise my bills.
I was anyways also thinking of doing some lightweight work in the backend, so I figured to use Parse. Now the call to the Google API is done in Cloud Code. But a new problem I'm facing is how to secure calls to the Cloud function I've defined in Parse? The Parse App ID and Client Key aren't secure at all.
All of Parse's blogs keep talking about creating users and defining ACLs etc. But in my case, there is no data in my Parse app and there is no user per se. It simply calls the Google API and returns the result. All I want to do is secure my cloud function so that it only accepts requests from my iOS app. How can I do that?
The inherent security risk here is that any key you store in your app is vulnerable, for that reason encryption is also vulnerable. My recommendation is to use the automatic user in Parse on your iOS app, you could even throttle excessive requests/abuse by a single user. By creating and using a user you are able to gain the benefits of ACL which appears the best security option available in Parse currently. At that point you send the automatic user in your cloud code request and verify it's a valid iOS user.

Resources