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

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

Related

Is there a way to default disable users in a firebase authencation on signup?

I am currently developing an iOS appplication using xcode and Swift. My application works well with firebase including the function of email verification. Due to the nature of my application, I want users to be able to sign up, verify their email and then await further verification on the side of my client using firebase.
In an ideal world, firebase would have a setting that supports user being automatically disabled on signup, and you would just tick a box and the user would be enabled in the authencation page of the console.
Seeming as I am looking for my client to be able to do this, I need a way that is simple to them, so they can enable and disable accounts. There is a property in the firebase authencation page but no way to default it.
So.. My idea was to create a cloud function in firebase that automatically disables users on signup, and once my client has verified who they are they will enable them. Any ideas on what this function would look like? Disabled is a nice and easy boolean value so.
I am new to firebase, so wondering if anyone had came across this kind of issue? The link below shows the function on user creation.
https://firebase.google.com/docs/functions/auth-events#trigger_a_function_on_user_creation
You can add an Admin SDK function in the user creation event you have. See this for an example: https://firebase.google.com/docs/auth/admin/manage-users#update_a_user
The easiest way to automatically disable new user accounts is through Cloud Functions. See for an example the answer to this question about How to prevent new user registration on Firebase?.
But note that the user will already be signed in by the time the Cloud Function runs, so they'll have access until their current/initial ID token expired (up to an hour).
The proper solution is to check whether the user is verified before enabling any backend functionality. For Cloud Firestore, Cloud Storage, and Firebase Realtime Database, you can do this in their server-side security rules. See for some examples of this:
(Firebase) Firestore security rules - allow if email verified without custom tokens?
Security rule to only allow write for users with verified emails
How do I lock down Firebase Database to any user from a specific (email) domain?

IOS Offline Login

Stange question, I'm looking to create an app for the company I currently work for which will hold all passwords for the software and platforms we use. I would like to be able to create some kind of login or authentication without connecting to the internet or using a post to HTTP.
Is this kind of thing possible? Even if I was to keep it to one username and password across the board. Or is it going to be better to only distribute to people that I know?
The only reason I want to do this is so that when downloaded from the App Store it would be only engineers that could login.
Thanks in advance!
For this you can add json file that contain all the data of the users for initial state and for user registration you can use core data. But you want to syncing with registered data and json file you need to fire silent api call to server.

Security Concerns with Firebase Simple Login

I've been using Firebase as a way to synchronize data between a Rails application and a mobile web-kit based application. I've recently been attempting to use the email/password authentication method in lieu of custom auth tokens.
Everything works as expected, but my concern is with user creation and authentication.
Currently, I'm able to create a user, both on Rails (using a self-modified version of the firebase-ruby gem) and through the mobile app, using the firebase node module.
So from the stance of a malicious user, is it correct to assume that I can create a Simple Login user with the JS library (for anyone's firebase instance), and then authenticate with that user, and attempt to read any data that they have stored?
Of course one shouldn't leave their entire Firebase data structure unprotected. So this only works in a situation where one has only set up the default security rules.
Either way, is there any way to prevent anyone from creating users, except for myself (or some other authorized person) without resorting back to custom authentication? I understand the difference between authentication (the server knows who you are) and authorization (the server is letting you in).
Any feedback is appreciated.
In my conversation with Frank, it appears that there is no way to prevent malicious users from creating any number of accounts on a Firebase instance through email/password Simple Login. This doesn't allow them authorization to any data per se, but could be annoying for the SysAdmin/DevOp who was maintaining the Firebase instance.

how to use GoogleAuthenticator for tfa (two-factor authentication) in a custom non-google login webapp

ok, I've spent 2 hours googling on what it is & how to use it in a web-application! but no success.
Most of the links talk about scanning codes or entering some key in the GoogleAuthenticar mobile app and it'll return changing verification codes every 30 seconds.
Few things :
The webapplication has it's own login. That means users don't login using Google into the webapp.
If an attacker gets the user's password, he sees the QRcode as the next-step, which he can scan directly with the GoogleAuthenticator app in his mobile (as far as it appears to me). How is it tied to user's mobile only ?
In various sites, it mentions a shared secret between user & server, that means at the time of signup, we provide the user the shared-secret, which he can use in her mobile GoogleAuthenticator app and then use it while reading the QR code ?
In the above case, how to proceed if the secret is lost or forgotten by the user ? Use forget secret to send the secret again to user's email ?
I am confused about how can it be implemented in a fashion when it's a non-google non-android application!
All I get is that, it's just a concept asking for our own implementation with some help from the source-code of the GoogleAuthenticator. Please correct me ?
What I think is the solution is that, we have to write our own mobile-app, just like this guy mentioned here, although I'm still not sure how will the secret between the mobile-app and the server will be unique with each installation of that app such that it identifies a particular user only or is there any way to write our own app and use GoogleAuthenticator mobile app without having Google-login in our webapp ?
Google Authenticator (the mobile application) implements the Time-based One-time Password Algorithm. In the scenario you are asking about, two-factor authentication would work as follows:
The user generates a one-time password to be validated by a server application.
The server would verify the password using the procedure detailed by the TOTP algorithm.
The password generation on the user device can be performed by any application implementing TOTP which has been "configured" for your user account. Configured here means having shared a secret with the server, as you mention yourself in the question.
Now, trying to answer your questions:
The fact your application uses its own set of user credentials or Google's has no direct effect on two-factor authentication. No matter what these credentials are, you need a way to identify your user (the username) in order to be able to proceed to the validation of its TOTP password, because you need to know who the user is. Said another way: using TOTP and using the Google Authenticator application does not imply having to use Google credentials on your site.
I'm not sure I understand correctly. The configuration of the Google Authenticator app for each account is performed only once. If an attacker is sitting right behind your back and takes a photo of your screen while you configure Google Authenticator, then yes, he'd be able to configure its own application with your credentials reading the same barcode you're using. Nevertheless, he'd also need your credentials (proper) in order to perform the login and then provide the one-time TOTP password. Anyway, this is a security problem which stems from how the user improperly handles its own credentials and you could be subject to similar problems no matter the technology you use. To make an imperfect metaphor, it's like asking "if the user leaves the pin card with the codes on the table, an attacker sees it and steals a photo of it, could it use them?". Sure, he could.
Yes, reading the barcode is one of the ways you can configure the application and sharing the secret between the client application and the server. You can use other means, such as entering the key manually into the application, but using the QR code is quicker and much less error prone. You won't even need to generate the QR code, because you could use Google's Web APIs as I explained in the blog post you were reading when you asked me to answer this question. In fact, the Java server side library described there uses the Google Web API's and returns you an URL for the user to check out and read its own QR. If you want to build your own QR logic, go on, but there's no compelling reason you should do that if you're eligible to use Google's APIs (which is something you should check anyway).
If the secret is lost it depends on your own policy, if it's your own application. First of all, you should invalidate the old secret immediately upon user notification. Then, you could use the scratch codes you may have given the user upon creation of the TOTP secret to verify his own identity. If he has lost the scratch codes too, you'd probably want to fall back to some other ways to verify his identity such as using some kind of backup information in his account (backup telephone numbers, security questions, etc.). Once the user identity is verified according to your standards, you would issue a new credential and would begin from the start: that is, reconfiguring the Google Authenticator using a new QR and/or a new secret key.
To summarise: yes, you can use the Google Authenticator application as your client front-end if you want to: there's no need to build another one. The only thing which you should into account is that Google Authenticator uses 30-second windows in its TOTP implementation: the server side logic verifying the TOTP password will have to use the same window size (which is, IIRC, the standard value proposed by the TOTP RFC).

In objective-c is it possible to set up OS-level account validation like Twitter, Facebook and Vimeo?

I'm working on an iPhone app that is logging into a webservice and it's been asked of me to get the account login management into the settings page (i.e. next to Twitter, Facebook and Vimeo). From what I've been reading about the accounts framework, it appears that only those few companies have that ability.
I currently have it set up and working asking for login info periodically and polling the webservice for validation, but we're trying to move toward supporting moderately offline use, which means we need to have some sort of account info managed on the phone itself.
Can I use the built-in account framework for our own login credentials or is that not something that's available to a regular dev and I'll have to look for another way to do it on my own? Is that something that the keychain would be better for?
Using the keychain to securely store the users credentials is a good idea to start.
If I am understanding your question about a "built-in account framework", I don't believe there is a local framework for account management on the device itself that I am aware of that would be useful in this circumstance.
I've had to build an app that needed to authenticate to a web service that also needed to have some offline access. I ended up recording the validated authentication date and time in the NSUserDefaults and would let the user use the app for a 48 hours period before they had to re-authenticate. Their data was queued locally and when they had online access again, I would re-authenticate and then sync the data. Not the most elegant solution but it fit the project.
I used AFNetworking (http://afnetworking.com) to track the changes in network access and used to blocks to respond to the changes.

Resources