Restricting user authentication with Firebase - firebase-authentication

I'm using Firebase to authenticate the users on my application but, since the app is very early stage, I would like to restrict the login (or registration) to only users that have a specific code.
It looks like there's no option like this and I was wondering if there's any solution that doesn't involve a back-end.
Right now I'm using a specific code in the database that the user has to enter while logging in. If that code is not correct you can't login. The problem is the function (obviously) is executed on the front-end so a person with the right knowledge could easily modify the code and still access without token.
Is there a more robust solution?

if you truly want no back end, you can see my answer at the bottom here How to protect firebase Cloud Function HTTP endpoint to allow only Firebase authenticated users? , which involves taking advantage of the fact that every firebase project is also a Google cloud platform project and GCP allows for private functions.
however, there is an easier way: just wrap your cloud function logic with an if clause that checks for any of a number of things before actually executing the function
assuming, for instance, you're on the web platform, when someone invokes an HTTPS callable function from the front, it will be sent with data and context objects.
you could check for context.auth.email to restrict to specific users. or you could check for data.mySecretKey and since the check is occurring in your cloud function, no one could inspect your code to find the key.

Related

Shopify app access token - how to make it more secure?

When store owner installs my app I save access tokens into database for later use. Having access tokens from store is huge security responsibility because anybody with these tokens can modify stores from any domain/address, there is no ip or domain lock.
What method could I use to make this more secure? I was thinking to save tokens offline and then upload it only when needed (in case I need to make some global updates for all stores), then delete it again. In case when merchant access app configuration within admin, I would just save it into session. Is there any better method?
Good question.
I save them in a database as well but I encode them with a separate key from the Shopify App password. That way even if someone have access to the database because of some backdoor entrance he won't be able to use them. That said if someone have access to the code he will be able to figure out how to decrypt it since he will have access to the key.
That said I make sure that each and every request is authenticated before I show any response from the server. Since I'm using NodeJS as the back-end I make sure that there are no global variables that can be accessed or modified from different stores. Everything is neatly scoped in separated functions so that the session is scoped for the current store and no other ones will be able to dirty the other store session.
In addition I make sure that there is a webhook that fires when the client uninstall his app in order to clear my database from any information regrading his store.
I know some people are using sessions for this ( online method ) but they pose other problems that I didn't like so I stuck with a database ( offline ) since that is the quicker way to access the App instead of multiply redirects in order to save the session.
As for proposals I can give you a few tips that I learn on my way while building a few basic Apps. ( I'm not an expert on the subject by any means )
don't rely on any cookies when it comes to sensible information
authenticate every request that comes from the front-end
don't trust the user and validate any input that comes from the front-end
don't over-complicate your setup, while it's good to have high security it's bad if it makes your app slow for the user and you lose customers
look to other ready to use popular solutions that can guide you to the correct path
don't get greedy with the App scopes, only request the scopes that you need for you app
remember to clean up after yourself when it's possible but don't over do it ( too many Apps modify the code of customers and break it only to prevent any way to clean it afterwards ) Example use the ScriptTag API instead of a liquid snippet using the Asset API. If you have to use the Asset API add only the parts that you know that won't break a site. Creating a variable is ok if you are using var if the site supports IE11 creating a variable using const or let is not OK or using vanilla JS is OK but using jQuery without knowing for sure that the site has it installed globally is not OK.
More insights on the matter can be seen here:
https://help.shopify.com/en/api/getting-started/authentication/oauth/api-access-modes
https://community.shopify.com/c/Shopify-APIs-SDKs/Best-way-to-store-shops-that-have-installed-my-app-and-their/m-p/402972

How to implement a one time authentication mechanism?

I'm trying to create a website to authenticate users through the use of a throwaway password where the assumption is that the user might not use the website again (basically a one time access).
I have done my research on OTP and various solutions to authentication but these don't seem to fit my requirements, most of them seem to rely on users having login credentials to the website whereas my system would allow them access without the need for registering.
The implementation of passwordless authentication by Auth0 seems to fit what you're describing. Even if you were not considering a third-party provider it may be useful to go through the documentation.
Basically, a user can login to a site without any need for a sign-up process. They can do so just by requesting that a one time code is delivered to them, for example, either by email or SMS.
This way, they can get quick access without having to setup a user and in the event that they do come back your application can recognize this because they will most likely be using the same mechanism, that is, you can use the email or mobile phone as the unique identifier.
Disclosure: I'm an Auth0 engineer.
If you do not require your users to register, why do you need authentication at all?
Why not just set a cookie with an unique identifier on the first visit? You can store data at the server side associated with that identifier. Keep track of when you last saw the user, and if they do not return within a certain period, you can delete any data you stored for that user.

Is Firebase's built-in authentication able to be used on a 3rd party server?

I'm looking to create a game server backend for a game I'm creating. We're currently using Firebase for handling of data and ads, and Firebase has built in authentication. Is it possible to have a user log into our app via Firebase's auth system, then confirm the user's authentication when they connect to the game server to ensure it's who they say they are?
Basically, after someone logs into our firebase, can we use that authentication information for a separate server, and what protocol/method would need to be used (if there's a specific one)
I've figured out the two steps you need to get the information required to auth, one clientside and one serverside. Note: the following examples are for the Java apis, but you can use any of firebase's equivalents.
Clientside: In the Firebase-Auth package, there's the FirebaseUser object. This contains information about their auth state, unique details, etc. There is a method here called getToken(), which will grab your token for the current authentication. Once you have this, you want to send it to the server when you need to auth.
Serverside: On the server, there's a FirebaseAuth object. Once you get the token from the client, you can use verifyIdToken(), which will confirm this is a valid token and give you the details about the user when you get the result. I suggest cross-checking the UUID against one a client sends, to just confirm someone didn't get their hands on a token and send a random ID.
Hope this helps.

secure the code in google chrome extension

I want to write a google chrome extension, that should make a request to my website to send and get some data, so, actually I should do an ajax request like it is written here https://developer.chrome.com/extensions/xhr.html
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://api.example.com/data.json", true);
I wanted ask if there is a way to somehow secure the code or prevent others from using my api, because actually the other users can see the source code of the extension when they install it and so use my api without me being aware of it.
EDIT:
If I need to make some sort of authentication, than how can I authenticate the user before making the ajax call ? for authentication I will need to send a request to my server , but for that I should send , e.g. username and password, that should be saved somewhere in the extension's files, which, in fact, can be seen by the users, when they install the extension.
Thanks
Don't trust the browser, take steps to authenticate the user instead. So, in this case, you could require that YOU enter in a password that is used to communicate with your server.
Your Google extension would simple require you to enter in a password before it attempts to use AJAX to communicate with your server.
Be aware that you should build in means of protecting yourself from brute-force attacks. So, do things like lock everything down if there are more than some small number of wrong passwords, etc.
You could also consider using the password to simply decrypt the destination of the XHR, but if you go this route, you should store this very carefully, because this will be brute-forceable offline.
EDIT
Trying to lock down an API so that only a single application can use it is just not practical nor technically possible, so you're only hope of doing this is to authenticate the user using the API, regardless of the accessing software he is using. You could have the user sign an agreement that legally limits them to only your extension, but I suspect this will go largely unenforceable and will consume your time tracking abusers down.
If you don't want unauthorized people even knowing where the API is, you could perform authentication using an out-of-band mechanism: over the telephone, email, SMS, or simply, another API that will grant the user a password or token that requests to your API must be accompanied with.
During this out-of-band process, you could also grant the user, a unique URI (the API access point) that is only valid per authenticated session (https://api.totally-cool-extension.com/api/ijyeDvB5dYvSiWG97OLuTAoNWwbhuZ0/, for example). Any requests to your server on OTHER URIs simply won't work. However, this isn't theoretically much different than using the same API access point, and having a good password. It just changes the number of places in your architecture that will be performing authentication and/or authorization checks.
<aside>My vote would be to reduce the number of authorization/authentication points to as few as possible so that you can spend more time on getting that one place correct rather than having multiple places and possibly multiple logic flaws or other things that could lead to vulnerabilities.</aside>
You could also explore using Public Key Infrastructure and/or one-time passwords schemes or device-based token generators, etc., but in the end, you'll be allowing authenticated and authorized users to use your API. And, thanks to the Internet, this will not remain an undisclosed URI for long.
And, more importantly, it will not prevent someone from using the data on their own. Even with all these measures in place, it would be trivial for an authorized user to collect this data as it is being streamed to your extension. Or, if you employ point-to-point encryption, they could screen-scrap or use some form of JS introspection on your very code or even extract the data from their computer's memory.
I know you were looking for a silver bullet here, but it doesn't exist.
I think you are doing it wrong. You should never trust what's going on on internet users PC's. Never!
Move the line of trust one step inward, make your API public and then design the security where you have perfect control - server side.
I could not get correct aspect of your use case
Few Points:
Your extension code is always traceable( Any one who has installed extension can view the code)
If you are looking for security through complicated or obfuscated coding patterns you end up slow down of understanding process not the whole.
If your target is to ensure users who install your extension should be able to access and inert all other users( Who have gained illegal access or downloaded and edited code) have a session shared key per installation.
Please explain further use case so i can help you better.

GWT: Authentication for some part of application using GWT login page

My application has some features that are accessible to all users, and some other features to which access should be restricted to authenticated users only. All these restricted features exists within some set of GWT Places, thus, all Places available in application can be divided into two groups: "accessible for all", and "restricted". In my opinion, places with restricted access, could implement some interface (let's say it would be RestrictedAccess), and if user proceeds to one of them, and it has not been authenticated yet, it will be redirected to the login screen - it's more OO-approach than applying filters basis on URL.
What I'm trying to achieve is:
Information about if user has been
authenticated or not should be
stored on server (it's not something
that could be stored in a cookie...)
Login page is a standard GWT place+view+activity (!)
User name & password validation is done on the server side.
So far, I've introduced RestrictedAccess interface, which is implemented by some set of places. My FilteredActivityMapper.Filter implementation, which is passed to the FilteredActivityMapper wrapping application activity mapper has the following logic:
Place filter(Place place) {
if (place instanceof RestrictedAccess && !userHasBeenAuthenticated()) {
return new LoginPlace();
}
// return the original place - user has been already authenticated or
// place is accesible for all users
return place;
}
private boolean userHasBeenAuthenticated() {
// remote call - how to do ???
}
The problem is with userHasBeenAuthenticated() method (user should not be redirected to the LoginPlace, if it has been already authenticated). If I want to store this information on the server-side, I have to do GWT RPC/request factory call here, but both are asynchronous, so I cannot work on its result in the filter method.
I know that I can use web.xml filters or some external framework (e.g. spring security), but none of this approach allows me to have login page as a standard GWT - based form, or indicating in the more OO way that access to some place should be restricted.
Thanks in advance for any hints
EDIT: I've started to wondering if places filtering (restricted/not restricted) should take place on the client side at all. If, as it was suggested, there is a possibility to hack code indicating if user has been authenticated or not, there is also possibility to hack places filtering code, so that it will be possible to access restricted places without signing in.
Piotrek,
I think there is a security issue with calling userHasBeenAuthenticated() - it would be possible to hack the client side code to return true every time this function is called.
The solution I've implemented is to simply return SC_UNAUTHORIZED if an unauthenticated user attempts to access any remote service. I've overridden the RequestFactory onResponseReceived function which redirects to a login page if the response is SC_UNAUTHORIZED. Idea taken from:
http://code.google.com/p/google-web-toolkit/source/browse/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/client/GaeAuthRequestTransport.java
This works for our situation where the Activities and Places are all data-centric - each place change retrieves data from the server. If a user isn't authenticated they simply don't get the data and get redirected to a login page.
I realize your situation is slightly different in that some places are accessible to everyone, in which case you could configure only the restricted services to return SC_UNAUTHORIZED.
I have a similar application with the same requirements. As yet I have not got round to to the implementation but I was thinking along the same lines.
What I was planning on doing is storing the authentication state client side in an AuthenticationManager class. When the app starts I was going to request the login info from the server (I was thinking of running on app engine so I would get the authentication state and also get the open id login/logout URLs) and store this in the AuthenticationManager. Acegi/Spring Security works in a simlar way so this info is available server side if you use those too.
When the user logs in/out they will be redirected by the server and the new state will be retrieved. This should keep the client authentication state in line with the server. Each RPC request on the server has to be checked for authentication too. I was using the gwt-dispacth library and this has some rudimentary authentication checking and cross site script protection in in too (although I think latest GWT has this for generic RPC).
One issue is session timeouts. Again the gwt-dispath library has some code that detects this and returns session expired exceptions to the client which can be intercepted and the auth manager updated.
Hope that makes some sense.