Search code examples
androidflutterfirebasebrowserone-time-password

Why might I be seeing a reCaptcha when doing Phone Auth?


Why does a web browser open up in Android when requesting an OTP using Flutter and Firebase, and what it has to do with Play Integrity API ? Will the web browser stop appearing when the app is published on the Google Play Store, and if so, why ?


Solution

  • Why might I be seeing a reCaptcha when doing Phone Auth?

    An attestation request needs to be completed before a OTP SMS message is sent to prevent fraud and abuse of the OTP service. Previously, when using OTP with an application, it would use SafetyNet to complete the attestation request. As a fallback in the event that SafetyNet could not complete successfully, reCaptcha would be used in place of SafetyNet.

    Recently, SafetyNet was announced for deprecation and the Play Integrity API would take its place.

    The Play Integrity API combines several integrity verdicts for developers to attest that the device and application can be trusted. In the case of authentication with OTP flows, the integrity verdicts are device integrity and application integrity. Both of those verdicts need to succeed in order for a successful OTP SMS message to be sent to users. In order to run device integrity, it runs something on the device to confirm that the device is a genuine device. In order for a successful application verdict to be returned, the application needs to have a matching SHA-1 and SHA-256 certificate fingerprint to that which is listed in Google Play.

    Important

    If you are not deployed to Google Play, get your app from a different app store with a different key, or are using a debug version of the app, the device verdict may succeed, but the application verdict may fail. This will cause the app to fallback to reCaptcha attestation rather than Google Play.

    How do I get the right certificates registered?

    In order to get the right certificate fingerprints registered in the Firebase console, you can check whether or not you use Google Play Signing (most apps do) and grab those fingerprints from Google Play: SHA1 and SHA256 fingerprint from Google Play

    Then, match those fingerprints to those registered in the Firebase console: Firebase Console showing matching SHA1 and SHA256 fingerprints

    If you are still seeing reCaptcha messages after setting Google Play Signing fingerprints in the Firebase Console, then I would use Peter's Asset Link tool to confirm that the locally deployed version of the app (on your phone) has matching fingerprints:

    Peter's Asset Link Tool showing matching fingerprints

    If the fingerprints all match, but you are getting an error message that:

    This request is missing a valid app identifier, meaning that Play Integrity checks, SafetyNet checks, and reCAPTCHA checks were unsuccessful. Please try again or check the logcat for more details.
    

    This could be due to a missing SHA-1 or SHA-256 certificate fingerprint from either Google Play Signing, Debug Key, or Upload Key.

    If you get reCaptcha attestation, but no SMS message

    If you are getting a reCaptcha, but no SMS message after following the steps to register all the certificate fingerprints above, then one last effort you may want to do is validate that you do not have an Application Restriction in place on your Android key for Firebase. Here is a sample of what the preferred application restrictions should look like:

    Application Restrictions for Android Apps

    The Android app when falling back to reCaptcha will reuse the API key found in the google-services.json file. Since you are falling back to reCaptcha, the browser that is being used on the users device will have a different certificate fingerprint than your application, and therefore will send that certificate fingerprint instead of your applications. Therefore, since its falling back and sending a different certificate fingerprint, likely not in the allowlist pictured, it would fail reCaptcha with an error message like the one seen previously in this answer.

    WARNING

    If you are currently using this API key for things outside of Firebase (other paid Google services), you could run into a potential abuse of your API key. Please consider creating separate API keys as outlined in this documentation. This is also called out specifically in the documentation here.

    What version of AppCheck do I need?

    AppCheck and Phone authentication are two separate products. Yes, Phone authentication does use Play Integrity to complete its attestation request, but it embeds Play Integrity within its package and AppCheck is an unnecessary step to enable Phone Auth. Having said that, adding AppCheck is always a good idea to boost the security of your application as it will provide attestation to your client requests to specific Firebase endpoints.

    One thing to note

    There was also recently an outage regarding Firebase Phone Auth and Play Integrity, but that has been resolved since posting this message.