firebase / firebase-admin-node

Firebase Admin Node.js SDK
https://firebase.google.com/docs/admin/setup
Apache License 2.0
1.62k stars 369 forks source link

[FR] Expose firebase phone auth's internal reCAPTCHA response token verification #2110

Open Durisvk opened 1 year ago

Durisvk commented 1 year ago

Is your feature request related to a problem? Please describe. Firebase Phone Authentication flow according to what's available currently supports the following flow:

  1. User enters a phone number
  2. Firebase frontend authentication logic is launched (this includes reCAPTCHA verification and sending a OTP code over text)
  3. User enters the verification code and submits the form
  4. Firebase either creates a user if the user did not exist before or it authenticates an existing user if they are already registered within the system.

This doesn't allow splitting Login and Signup flows and that is very frustrating. Our solution currently is the following:

  1. User enters a phone number
  2. + We invoke our internal API which verifies whether the user with this phone number exists or not a. If the user exists and this is a Login flow we let them continue and launch the Firebase frontend authentication logic b. Otherwise we redirect them to sign up flow
  3. Firebase frontend authentication logic is launched (this includes reCAPTCHA verification and sending a OTP code over text) ... and the rest of the flow is the same ...

This is prone to a brute-force discovery attack. An attacker might be able to brute-force guess the phone numbers and invoke our API endpoint which checks for existing users to get all the phone numbers in our system.

To solve this we need to secure this endpoint with a reCAPTCHA.

The problem: Firebase already uses reCAPTCHA but it's not available to us developers. We can call RecaptchaVerifier.verify() but we cannot validate the token on the backend because the reCAPTCHA secret (required here: https://developers.google.com/recaptcha/docs/verify) is not provided to us.

Describe the solution you'd like Either expose the internal Firebase's reCAPTCHA secret to us in some way through Firebase Dashboard or GCP dashboard so that we can reuse it for our validation.

Or expose a method in firebase auth such that:

  const myToken: string = req.query.response // await new RecaptchaVerifier().verify() string result

  await firebaseAdmin.auth().verifyRecaptchaResponse(myToken); // can throw or return something, up to you

  await checkIfUserWithPhoneExists(req.query.phone); // this is now protected from brute-force discovery attack  

Describe alternatives you've considered

  1. Setup a separate reCAPTCHA application at https://www.google.com/recaptcha/admin

    • that would require user to pass through two reCAPTCHAS which is not the greatest experience.
  2. Use rate limitter on the endpoint which is responsible for verifying whether the user already exists.

    • Rate limitters are unreliable in nowadays era and there's no better and more secure form of protecting such endpoints than reCAPTCHA nowadays

I was also looking throughout the Firebase Admin dashboard and GCP dashboard to look for a secret key that I can use to validate the reCAPTCHA token but I just couldn't find it.

google-oss-bot commented 1 year ago

I found a few problems with this issue:

ngdbao commented 5 months ago

I'm looking for this method too. I don't want to implement 2 separated recaptcha challenges for 2 purposes (authen phone and own purpose) Instead, ability to validating firebase recaptcha on my server-side would be ideal