My company that I'm interning at is currently using Firebase push notification tokens for authentication from the mobile app to the backend and I am not sure if this is a good practice. The way it works is as follows:
FirebaseInstanceID service issues a unique token for every device as
soon as device starts
Mobile user sends login info to server; if server authenticates, the
mobile app then uploads the Firebase token to the database and it is
stored with the user such that the token matches with the user
On any subsequent logins, user sends the Firebase token retrieved from FirebaseInstanceID service to the server; the server attempts to match the token with a user
On clicking logout, mobile phone sends an empty token (i.e. empty string) to the server with their associated username
I have a feeling this is a very bad way to do authentication but I don't quite know why. According to my research the conventional way to do is that the server sends a temporary session ID to client, client stores it securely, and sends it to server for any subsequent requests. Can somebody explain what's going on with this Firebase business and why its good or bad?
The problematic your company is facing, from what i understand, it to authenticate devices with a back-end API.
Actually when it comes to mobile applications, it is a tricky question. If users do not have to authenticate personnally, you still don't want to open your services to anyone. So you want to have an automated authentication system that runs in the background of your mobile app and that identifies devices or app instances.
To do that you need two things : 1 - identify a device (or an app instance) in a unique manner. 2 - make sure that the used string to identify the device/app instance comes from a real device/app instance.
Firebase instance ID is maybe right now the best free way to do that. The mobile app asks for google services to generate the unique token. The mobile app then sends the token to your back-end API for authentication.
And then the back-end API makes sure, during authentication, that the sent token comes from a real app instance by making a request to google services. Google services ensure that the token was generated on a real device (android/ios) and refer to an instance of your app (and not a tampered one).
This is a good way of delegating security issues that I exposed above to google services (who probably are better than you if you're not a security expert).
Of course there are other security measures that you should take to ensure your back-end API integrity. Such as HTTPS, for instance..
So I guess when it comes to mobile development, we should hope for a better solution than that, but since there are no better solutions, using firebase instance id is not bad practice.
Hope this helps
Related
My mobile app does some API calls during usage and some of them should not be possible from anywhere else (e.g. postman)
For instance if you have a database table user and a column membership and the app-user does an in-app-purchase an API call is made to update that row and change the column from e.g. standard to premium
Now in theory if someone knows the URL and sends an HTTPS request he could upgrade himself without purchasing anything. I am researching for a while now but feel a bit lost. There is no registration or login. I use the unique hardware ID of the users devices as a primary key to store everything in the database. I thought about something like:
When the user opens the app a request is send and the server responds with a randomly generated key
All requests the user makes have to use that key which I would send in the header otherwise it gets rejected
Is this the only thing I can do? What is the best practice for a mobile app that does not use any kind of registration?
If it matters I used flutter for the app and flask for the backend that is connected with a postgres database
edit: I am using HTTPS everywhere not HTTP
If the api is open as you have described in the architecture then there is no way this can be achieved without having a login mechanism like OAuth or one of those provided by Google Login or Facebook Login. You will have to provide a way for client device to tell you who are you talking with.
Else you can hide this api behind a closed network so that only server can call this api which will only do so after a successful response from the payment gateway. That way you can enable the hit to come only from the specific server ip address.
Also the fact that you want HTTP instead of HTTPS makes this very vulnerable to a number of attacks.
I would like to create an app (which will be public) that would send and receive some data in real-time to/from a server. Because for this particular use case the PUB/SUB pattern fits naturally, I was thinking about using the MQTT protocol with TLS. What are some best practices for securing access in such cases?
Would it be safe to only have one user with password for the mobile apps registered in the broker (like Mosquitto or RabbitMQ) and use ACLs for limiting client by ID for topics and store these secrets in the mobile apps? If not, what would be a suitable solution? (If using individual user in broker for each app account wouldn't it be a performance issue, given the potential big number of users?)
Are there any other schemes for allowing secure access from the mobile app to the broker?
No, a single username/password is a REALLY bad idea. (All it takes is somebody to disassemble the app and the username/password are compromised and anybody can impersonate anybody else). Also linking clientIds to users probably means users can only have a single device.
Having a user sign in with a username/password should have minimal impact on performance as it will only be checked at connection time.
It also means you can revoke the username/password of a single user and not have to ship a new version of the app.
An alternative to username/password is to issue a certificate to user for them to authenticate with the broker. The CN from the certificate can be used to identify the user.
If you use EMQ X MQTT Broker, the application can send messages to the application server through an HTTP request, the application server will authenticate, record, check, and then invoke REST API of EMQ X Broker to publish the message for the application agent.
The application can be sent only after it has passed the verification, and the sending operation history can be recorded
Here is the idea:
There is an android application that will consume services that I will create using Spring. However, this services should have some sort of security, so only people logged in on my android app can consume such services.
On my android app, I will use Firebase to do the authentication, using email and password. So, there will be no need for me to configure any server to make this control. (Like Spring OAuth2)
The question is, once the user is logged on my app and wants to consume some service, for example GET LIST of something, that I will provide on the Server using Spring, how can I check if the user is logged on the app, so I can grant access to that service?
Your Android app will need to pass the user's token on to your app server, where you can then verify that the id token is valid and use the information in it.
See the Firebase documentation on verifying id tokens for full information, including this description:
If your Firebase client app communicates with a custom backend server, you might need to identify the currently signed-in user on that server. To do so securely, after a successful sign-in, send the user's ID token to your server using HTTPS. Then, on the server, verify the integrity and authenticity of the ID token and retrieve the uid from it. You can use the uid transmitted in this way to securely identify the currently signed-in user on your server.
Also note this first note in blue:
Note: Many use cases for verifying ID tokens on the server can be accomplished by using Security Rules for the Firebase Realtime Database and Firebase Storage. See if those solve your problem before verifying ID tokens yourself.
While it might not apply for your use-case, always keep it in mind since the most maintainable code is the code that you didn't have to write. :-)
I've been doing a lot of search about secure my api for mobile apps for Android or IOS.
Almost all examples tell user provides an user id and password somehow in a exchange for a token.
But how to prevent someone else to consume my api without my consent?
Face the following scenario:
I expose an API,
I develop, then, an app for android to consume it,
I develop, then, an app for IOS to consume it.
Other developer performs a rev. engineer in my app, creates his own app and starts to consume it without authorization.
How to prevent that?
Short answer: you can't.
Little longer answer: If you know what you are doing you can always reverse engineer a given application and use its api. You can only make it more difficult and time consuming, using authentification via tokens and device ids or usernames is a good first step. Apart from that: why would you want to close your api to outsiders? If your server code is written well there is nothing to worry about.
You can maybe secure your API on a legal basis and sue developers who use it, but that is a completely different topic.
Some clarification regarding securing the API and securing content via the API. Assume you create a server where you can send user/password and receive a token if that combination was correct. For the account-page you send said token over and the server verifys that that token is valid and returns your account page. You secured the actual content of the API. That is obviously very possible and almost a must-have unless you have no user-specific data. But still everybody can send the exact same initial request from their custom app, sending a user/pass and again receive a token, etc. You cannot really prevent the request itself or even determine that it was not send by some service not authorized by you. You can send some hashes along the request to add some security by obfuscation, but since your app has to compute them, so can the reverse engineer.
Yes, login api are open but they return a token only on successful match in your database. You should focus more on security of your data than unknown hits at your api.
SignUp API can be used for creating a user, and login for returning token of that user. Only if malicious developer has credentials, then he can access tokens and auth APIs. There is also something about DDOS attacks so you can maybe write logic to temporarily block IPs where hits frequency is high.
You can also store device ID of signing user, which seems idle for your scenario. Entertain hits from that deviceID only. Similarly, user can add more devices with their credentials. I think even Google does that (generate alerts if user creds are signed in from new device and add the device to list if user confirms). Hope this helps.
We are developing a mobile app which will talk to a backend service hosted on Amazon ec2. One part of the app is registration. The registration data will be passed from the phone to the backend ec2 server as rest/JSON. The problem we have is how to make sure the registration request that we receive in the amazon(from the phone app) is from a valid app and not from spammers/hackers? I can't store any id, public key or something similar on the phone app as a clever person can easily decompile the code and get that logic. I am sure there would be some solution out side which others have implemented.
Some solutions in my mind are: Some sort of Token Synchronisation/One time token etc.
Please suggest some good solutions people out there have implemented.