Security issue with verifying firebase token on server side? - firebase

I am using firebase mobile otp authentication. After successful authentication my android app receives a token which I have to verify on my django server. But while I was reading the docs of verifying this token, it comes out that if someone knows my firebase project-id, they can generate valid tokens anytime they want.
To get contec, look at the last method to verify firebase token at link
Isn't this quite risky, as once your firebase project id is known to someone, they can create fake tokens??
Also does custom authentication token help overcome this problem?
Thanks. Let me know if I have incorrectly understood the firebase token validation and it is not possible to create fake tokens once we know the firebase project-id.

ID tokens are signed by a private key owned by Firebase Auth. They cannot be forged. Note that the doc you've referenced also states:
Finally, ensure that the ID token was signed by the private key corresponding to the token's kid claim. Grab the public key from https://www.googleapis.com/robot/v1/metadata/x509/securetoken#system.gserviceaccount.com and use a JWT library to verify the signature.
A forged ID token will not pass the signature check.

Related

Which type of token does Firebase Authentication use?

I'm a little bit confused about the token that Firebase Authentication provides for a user when a user succesfully have been created. The tokens is seen here in the userID column:
I'm not sure what the right term for it is. Is it a JWT token, an ID token or something else?

How to verify custom Firebase Auth Token, created by createCustomToken()

I created custom Auth Token via createCustomToken(), see https://firebase.google.com/docs/auth/admin/create-custom-tokens.
But later on when I try to verify this token via verifyIdToken() function it throws following error
Error: verifyIdToken() expects an ID token, but was given a custom token. See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.
Which is rational, because there is no such ID... But what I need - is to simply verify the token, similar to jwt.verify()...
Has anyone came across this problem and what solution was found? Is it possible to verify Firebase auth token via jsonwebtoken library?
P.S. I am gonna use verification in Google Cloud Function endpoints
SOLUTION: Looks like I just found a solution https://firebase.google.com/docs/auth/admin/verify-id-tokens#verify_id_tokens_using_a_third-party_jwt_library Just need to grap public key from https://www.googleapis.com/robot/v1/metadata/x509/securetoken#system.gserviceaccount.com and use jsonwebtoken library to verify it...
verifyIdToken like the name is to verify IdToken, not custom token.
CustomToken is for client to sign in. This custom token can be verify using simple JWT verification like your solution (it expire after one hour).
But the IdToken is another story, you need to do sign in process using firebase auth.
To Get The Id Token from client after signIn, it's depend whether the client is Android, Web, or IOS.
The code to get the IdToken can be read in this section

not getting the customToken when trying to signInWithEmailAndPassword in firebase

from the below image in firebase docs they are saying that when user sign to app send their sign-in credentials with username(email) and password, they said that response will contain a custom token but for me in the response only showing access token and refresh token, if we use any of these two token for signInWithCustomToken getting an error of invalid token, please pull me out of this issue
Thanks in advance
I think you are misunderstanding this. For custom auth, you are typically using your own auth system and not Firebase. Following the docs, they assume you are using your own username/password auth system. In that case, you send both to your backend server. You verify the credentials (username, password) in your own auth system. If they are legit, you lookup the user id in your auth system database, you then use the Firebase Admin SDK createCustomToken(uid) to mint a custom token with that uid. You send it back in the response to the client. The client will then call signInWithCustomToken to complete the sign-in.

Using firebase jwt to authenticate users to external server\service?

Okay so in my iOS app I log the user into firebase, then get the jwt token. So now I have my server with an api which accepts an idtoken in the header of the GET.
What do I do here? Certainly I wouldn't be validating the JWT againt firebase on every single API call right? I mean its fast, but that adds latency with a second external check, no? How does one simply just decode that guy in C#? I have an Auth0 layer already and that decodes the JWT with my server-stored secret, but that same code doesn't work for the Firebase token.
Could it just be decoded then extract the user details from that, maybe just check expiry and if expiry > X months it's still okay?
In order to verify Firebase ID tokens and JWTs in general, you only make a network call on your server to get the public certs which are usually not updated for several hours. You could cache that and try to verify with an ID token and if it fails, only then, load the new public certs.
And yes, you must verify the ID token on each call especially since Firebase ID tokens expire after typically an hour and need to be refreshed continuously.

Firebase signInWithCustomToken handle token expiry

I'm using firebase 9.x with custom authentication. According to the documentation the token expiry cannot be more than one hour. Is there a listener which I can register to that will be called when the token expires.
The documentation also talks about automatic refreshing of tokens. I believe that is not applicable for custom authentication. Let me know otherwise.
https://firebase.google.com/docs/auth/server#use_the_firebase_server_sdk
Ideally the documentation (above) should have the requested information.
Thanks in advance.
The token that is generated server side (custom auth) is a JWT (JSON Web Token). This token must be supplied by your client (Android?) to the Firebase server to authenticate the user to Firebase. In the 9.x libraries, it seems these tokens now have a maximum life of an hour (i.e they are no longer accepted after 60 mins). (See Sam Stern's comment in this issue: https://github.com/firebase/quickstart-android/issues/31).
Sam indicates that once authentication has occurred using a custom generated token, the Android client will remain authorised until signed out.
If you actually require to know when your JWT token is valid until, it should be 60 minutes after you generate it on your server. If the token has not yet been used for auth with Firebase, at this point you could regenerate a new one and use that instead.
The documentation is misleading. It should say you have 1 hour to use the custom token to sign in. I also feel if the token is that temporary, then it should be single use. Otherwise it is confusing how they want you to use the token.
The SDK will take care of keeping the sessions tokens up to date IF YOU ARE SETUP correctly. For more info The custom tokens are only used to start a SESSION. So you have to have hour to use a custom token to SIGN IN. Once you are signed in and your Firebase Admin account and app configuration is setup correctly, the SDK can communicate back and forth with the Firebase back-end to keep the tokens up to date. Once you sign out with FirebaseAuth.signout(), you will need a new custom token to sign back in if it has been over 1 hour.
So in most cases, you really do not need to listen for token expiration
have you tried AuthListener?
mAuthListener = new FirebaseAuth.AuthStateListener(){
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
user.getCurrentUser().getToken(true);
// ...
}
};;
mAuth.addAuthStateListener(mAuthListener);

Resources