flutterfire icon indicating copy to clipboard operation
flutterfire copied to clipboard

🐛 [firebase_auth][iOS] INVALID_LOGIN_CREDENTIALS error message is not properly parsed

Open Arik-AOS-dev opened this issue 2 years ago • 6 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues and found no duplicates.

What plugin is this bug for?

Firebase UI Auth

What platform(s) does this bug affect?

iOS

List of dependencies used.

flutter pub deps -s list
Dart SDK 3.1.4
Flutter SDK 3.13.8
complete 0.1.0

dependencies:
- firebase_auth 4.13.0
  - firebase_auth_platform_interface ^7.0.4
  - firebase_auth_web ^5.8.7
  - firebase_core ^2.22.0
  - firebase_core_platform_interface ^5.0.0
  - flutter any
  - meta ^1.8.0
- firebase_core 2.22.0
  - firebase_core_platform_interface ^5.0.0
  - firebase_core_web ^2.8.1
  - flutter any
  - meta ^1.8.0
- firebase_ui_auth 1.10.0
  - email_validator ^2.1.17
  - firebase_auth ^4.11.1
  - firebase_core ^2.19.0
  - firebase_dynamic_links ^5.4.1
  - firebase_ui_localizations ^1.8.0
  - firebase_ui_oauth ^1.4.14
  - firebase_ui_shared ^1.4.1
  - flutter any
  - flutter_localizations any
- firebase_ui_oauth_google 1.2.14
  - firebase_auth ^4.11.1
  - firebase_ui_oauth ^1.4.14
  - flutter any
  - google_sign_in ^6.1.0
- flutter 0.0.0
  - characters 1.3.0
  - collection 1.17.2
  - material_color_utilities 0.5.0
  - meta 1.9.1
  - vector_math 2.1.4
  - web 0.1.4-beta
  - sky_engine any
- google_sign_in 6.1.6
  - flutter any
  - google_sign_in_android ^6.1.0
  - google_sign_in_ios ^5.5.0
  - google_sign_in_platform_interface ^2.4.0
  - google_sign_in_web ^0.12.0

dev dependencies:
- flutter_test 0.0.0
  - flutter any
  - test_api 0.6.0
  - matcher 0.12.16
  - path 1.8.3
  - fake_async 1.3.1
  - clock 1.1.1
  - stack_trace 1.11.0
  - vector_math 2.1.4
  - async 2.11.0
  - boolean_selector 2.1.1
  - characters 1.3.0
  - collection 1.17.2
  - material_color_utilities 0.5.0
  - meta 1.9.1
  - source_span 1.10.0
  - stream_channel 2.1.1
  - string_scanner 1.2.0
  - term_glyph 1.2.1
  - web 0.1.4-beta
- flutter_lints 3.0.1
  - lints ^3.0.0

transitive dependencies:
- _fe_analyzer_shared 61.0.0
  - meta ^1.0.2
- _flutterfire_internals 1.3.12
  - collection ^1.0.0
  - firebase_core ^2.22.0
  - firebase_core_platform_interface ^5.0.0
  - flutter any
  - meta ^1.8.0
- analyzer 5.13.0
  - _fe_analyzer_shared ^61.0.0
  - collection ^1.17.0
  - convert ^3.0.0
  - crypto ^3.0.0
  - glob ^2.0.0
  - meta ^1.7.0
  - package_config ^2.0.0
  - path ^1.8.0
  - pub_semver ^2.0.0
  - source_span ^1.8.0
  - watcher ^1.0.0
  - yaml ^3.0.0
- args 2.4.2
- async 2.11.0
  - collection ^1.15.0
  - meta ^1.1.7
- boolean_selector 2.1.1
  - source_span ^1.8.0
  - string_scanner ^1.1.0
- characters 1.3.0
- clock 1.1.1
- collection 1.17.2
- convert 3.1.1
  - typed_data ^1.3.0
- crypto 3.0.3
  - typed_data ^1.3.0
- desktop_webview_auth 0.0.14
  - crypto ^3.0.3
  - flutter any
  - http ^1.0.0
  - flutter_web_plugins any
  - plugin_platform_interface ^2.1.4
- email_validator 2.1.17
- fake_async 1.3.1
  - clock ^1.1.0
  - collection ^1.15.0
- file 7.0.0
  - meta ^1.9.1
  - path ^1.8.3
- firebase_auth_platform_interface 7.0.4
  - _flutterfire_internals ^1.3.12
  - collection ^1.16.0
  - firebase_core ^2.22.0
  - flutter any
  - meta ^1.8.0
  - plugin_platform_interface ^2.1.3
- firebase_auth_web 5.8.7
  - firebase_auth_platform_interface ^7.0.4
  - firebase_core ^2.22.0
  - firebase_core_web ^2.8.1
  - flutter any
  - flutter_web_plugins any
  - http_parser ^4.0.0
  - js ^0.6.3
  - meta ^1.8.0
- firebase_core_platform_interface 5.0.0
  - collection ^1.0.0
  - flutter any
  - flutter_test any
  - meta ^1.8.0
  - plugin_platform_interface ^2.1.3
- firebase_core_web 2.8.1
  - firebase_core_platform_interface ^5.0.0
  - flutter any
  - flutter_web_plugins any
  - js ^0.6.3
  - meta ^1.8.0
- firebase_dynamic_links 5.4.4
  - firebase_core ^2.22.0
  - firebase_core_platform_interface ^5.0.0
  - firebase_dynamic_links_platform_interface ^0.2.6+12
  - flutter any
  - meta ^1.8.0
  - plugin_platform_interface ^2.1.3
- firebase_dynamic_links_platform_interface 0.2.6+12
  - _flutterfire_internals ^1.3.12
  - firebase_core ^2.22.0
  - flutter any
  - meta ^1.8.0
  - plugin_platform_interface ^2.1.3
- firebase_ui_localizations 1.8.0
  - flutter any
  - flutter_localizations any
  - path ^1.8.2
- firebase_ui_oauth 1.4.14
  - desktop_webview_auth ^0.0.13
  - firebase_auth ^4.11.1
  - firebase_ui_auth ^1.10.0
  - firebase_ui_shared ^1.4.1
  - flutter_svg ^2.0.7
  - flutter any
- firebase_ui_shared 1.4.1
  - flutter any
- flutter_localizations 0.0.0
  - flutter any
  - intl 0.18.1
  - characters 1.3.0
  - clock 1.1.1
  - collection 1.17.2
  - material_color_utilities 0.5.0
  - meta 1.9.1
  - path 1.8.3
  - vector_math 2.1.4
  - web 0.1.4-beta
- flutter_svg 2.0.9
  - flutter any
  - vector_graphics ^1.1.9+1
  - vector_graphics_codec ^1.1.9+1
  - vector_graphics_compiler ^1.1.9+1
- flutter_web_plugins 0.0.0
  - flutter any
  - characters 1.3.0
  - collection 1.17.2
  - material_color_utilities 0.5.0
  - meta 1.9.1
  - vector_math 2.1.4
  - web 0.1.4-beta
- glob 2.1.2
  - async ^2.5.0
  - collection ^1.15.0
  - file >=6.1.3 <8.0.0
  - path ^1.8.0
  - string_scanner ^1.1.0
- google_identity_services_web 0.2.2
  - js ^0.6.4
  - meta ^1.3.0
- google_sign_in_android 6.1.20
  - flutter any
  - google_sign_in_platform_interface ^2.2.0
- google_sign_in_ios 5.6.5
  - flutter any
  - google_sign_in_platform_interface ^2.2.0
  - pigeon ^11.0.1
- google_sign_in_platform_interface 2.4.2
  - flutter any
  - plugin_platform_interface ^2.1.0
  - quiver ^3.0.0
- google_sign_in_web 0.12.1
  - flutter any
  - flutter_web_plugins any
  - google_identity_services_web ^0.2.2
  - google_sign_in_platform_interface ^2.4.0
  - http >=0.13.0 <2.0.0
  - js ^0.6.3
- http 1.1.0
  - async ^2.5.0
  - http_parser ^4.0.0
  - meta ^1.3.0
- http_parser 4.0.2
  - collection ^1.15.0
  - source_span ^1.8.0
  - string_scanner ^1.1.0
  - typed_data ^1.3.0
- intl 0.18.1
  - clock ^1.1.0
  - meta ^1.0.2
  - path ^1.8.0
- js 0.6.7
  - meta ^1.7.0
- lints 3.0.0
- matcher 0.12.16
  - async ^2.10.0
  - meta ^1.8.0
  - stack_trace ^1.10.0
  - term_glyph ^1.2.0
  - test_api >=0.5.0 <0.7.0
- material_color_utilities 0.5.0
  - collection ^1.15.0
- meta 1.9.1
- package_config 2.1.0
  - path ^1.8.0
- path 1.8.3
- path_parsing 1.0.1
  - vector_math ^2.1.0
  - meta ^1.3.0
- petitparser 5.4.0
  - meta ^1.9.0
- pigeon 11.0.1
  - analyzer ^5.13.0
  - args ^2.1.0
  - collection ^1.15.0
  - meta ^1.7.0
  - path ^1.8.0
  - yaml ^3.1.1
- plugin_platform_interface 2.1.6
  - meta ^1.3.0
- pub_semver 2.1.4
  - collection ^1.15.0
  - meta ^1.3.0
- quiver 3.2.1
  - matcher ^0.12.10
- sky_engine 0.0.99
- source_span 1.10.0
  - collection ^1.15.0
  - path ^1.8.0
  - term_glyph ^1.2.0
- stack_trace 1.11.0
  - path ^1.8.0
- stream_channel 2.1.1
  - async ^2.5.0
- string_scanner 1.2.0
  - source_span ^1.8.0
- term_glyph 1.2.1
- test_api 0.6.0
  - async ^2.5.0
  - boolean_selector ^2.1.0
  - collection ^1.15.0
  - meta ^1.3.0
  - source_span ^1.8.0
  - stack_trace ^1.10.0
  - stream_channel ^2.1.0
  - string_scanner ^1.1.0
  - term_glyph ^1.2.0
- typed_data 1.3.2
  - collection ^1.15.0
- vector_graphics 1.1.9+1
  - flutter any
  - vector_graphics_codec 1.1.9+1
- vector_graphics_codec 1.1.9+1
- vector_graphics_compiler 1.1.9+1
  - args ^2.3.0
  - meta ^1.7.0
  - path_parsing ^1.0.1
  - xml ^6.3.0
  - vector_graphics_codec 1.1.9+1
  - path ^1.8.0
- vector_math 2.1.4
- watcher 1.1.0
  - async ^2.5.0
  - path ^1.8.0
- web 0.1.4-beta
- xml 6.3.0
  - collection ^1.17.0
  - meta ^1.9.0
  - petitparser ^5.4.0
- yaml 3.1.2
  - collection ^1.15.0
  - source_span ^1.8.0
  - string_scanner ^1.1.0

Steps to reproduce

To reproduce just follow the steps in the FirebaseUI Auth codelab, specifically:

  • Codelab Step 2: Follow the instructions, make sure to create a new Firebase project. I used the free 'Spark` plan with default settings.
    • NB This issue seems to be somehow related to the config of the Firebase project, so this is likely a critical step. See detaisl below.
  • Codelab Step 3: Get the starter code, or the 'complete' code from the Codelab GitHub Repository). I initially followed the entire lab but the Codelab implementation details don't affect this issue, so the easiest way is the shortcut and download the 'complete` project from GitHub
    • Note: I have had the same issue in all my firebase_ui_auth projects (also see Issue firebase/FirebaseUI-Flutter#25), but the codelab project is the easiest way to reproduce and is what I used to investigate this issue (details below)

    • Make sure to use flutterfire configure, per the codelab, to generate the firebase_options.dart

    • In my case flutterfire configure generated an error as follows: i Found 4 Firebase projects. Selecting project flutterfire-ui-codelab. FirebaseProjectNotFoundException: Firebase project id "flutterfire-ui-codelab" could not be found on this Firebase account.

      • Note that flutterfire-ui-codelab is another (my initial) Firebase project (it's actually flutterfire-ui-codelab-e0f34, so there is possibily a seperate bug here with flutterfire config), and not the new, clean Firebase project I wanted to use for this test. To circumvent I explictly specified the Firebase project to be configured using: flutterfire configure -p flutterfire-ui-codelab2-260ce. This successfully generated my firebase_options.dart file.
  • Skip Codelab Steps 4-8: These are not needed if you've downloaded the 'complete' code from the Codelab GitHub Repository). Use the following steps instead
  • Step 4: In theory the codelab 'complete' code should now run... However in my case it generated the following error (which flutter clean && flutter pub get does not resolve): Unhandled Exception: [core/duplicate-app] A Firebase App named "[DEFAULT]" already exists
    • This can be resolved in 2 ways (I've done both, with no impact to the issue here)
    • Step 4: Option a: The codelab 'complete' project has a GoogleService-Info.plist in the ios/Runner folder. Replacing this with the GoogleService-Info.plist from my own Firebase project is the simplest way to resolve the issue and will result in a working ios app displaying this issue
    • Step 4: Option b: Delete the ios folder and its content and recreate the ios content with flutter create . --platforms ios. This results in the same outcome as Step 4a

You should now have a working app which displays the issue documented here when run on an iOS simulator (I used both iPhone 14 and iPhone 14 Pro with the default (latest, I assume) iOS.

NOTE: There are 2 issues I identified with the codelab 'complete' code but which do not affect this issue here. For completeness these are:

  • Issue 1: The images in home.dart don't display in the app because the image path is missing assets/ before the image filename
  • Issue 2 (only arrises if Step 4b (ios re-create) is done): The widget_test.dart file (which is created when the ios app is re-created), does not recognise the MyApp() because the 'complete' code has a separate app.dart file for this class rather than it being part of the usual import 'package:complete/main.dart'; These issues are easily rectified, but as noted, don't effect the issue here.

Expected Behavior

The ios app should render reasonable user error messages in the app UI (via the SignInScreen widget) when the user enters invalid email and password credentials (either invalid / non-existent account, or wrong password).

Examples as follows:

image

image

NOTE: Having separate error messages for invalid / non-existent account and wrong password is, in my view, not a good security practice as it allows people to discover valid accounts and greatly simplifies hacking of passwords.

NOTE2: The error messages for web clients and android clients are different from the ios (expected behavior) messages above. The web client simply shows the text Error in red, while adnroid show different red text: 'An internal error has occurred. [ INVALID_LOGIN_CREDENTIALS ]' In my view it would be a much better UX to show consistent error messages across all platforms. Also see Issue firebase/FirebaseUI-Flutter#25 where this is also discussed.

Actual Behavior

When the user enters invalid email and password credentials (either invalid / non-existent account, or wrong password) the following raw error message is rendered to the UI via the SignInScreen widget:

image

Full message when scrolling down:

image

I view this as an unacceptable and unusable User Experience, and it would prevent me from using the firebase_ui_auth package.

Additional Information

I believe this issue may be related to how the Firebase project is setup. Hence the emphasis in reproduction Step 2 above.

The reason for this is that there is another - not very good way, but an instructive way - to resolve the Unhandled Exception: [core/duplicate-app] A Firebase App named "[DEFAULT]" already exists issue I encountered at Step 4 above. I'll call this Step 4 - Option c and will describe the behavior and my associated hypothesis

  • Step 4 - Option c: Instead of replacing the GoogleService-Info.plist file, or recreating the ios build, it is possible to get the app working - with the expected error messages ! by adding a name: parameter to the Firebase.initializeApp in main(). I discovered this while trying to debug the issue and from this StackOverflow article. Example as follows:
  await Firebase.initializeApp(
    name: 'test-app',
    options: DefaultFirebaseOptions.currentPlatform,
  );
  • This results in a working app with the expected UI error messages (and was used to generate the screenshots in the Expected Behavior section
  • However this results in weird behavior where users that we previously registered in my Firebase project are no longer available, but new users can be registered and logged in. Furthermore these same new users can be accessed regardless of the name: value used and don't appear anywhere in my Firebase project.

HYPOTHESIS:
Part 1: Using the combo of GoogleService-Info.plist and project.pbxproj from the original codelab complete folder seems to redirect my app to the codelab Firebase instance (PROJECT_ID flutterfire-ui-codelab referenced in GoogleService-Info.plist), which is why I can't see the users I've added there (like [email protected] and [email protected]) in my own Firebase project. Part 2: Somehow the codelab Firebase instance (PROJECT_ID flutterfire-ui-codelab) is configured differently than mine and this causes the invalid credentials UI error messages to work correctly, while my basic, free and default Firebase config causes the bad UI error messages.

I hope all this helps track down this issue and helps to get it fixed.

Arik-AOS-dev avatar Nov 13 '23 13:11 Arik-AOS-dev

Hi @Arik-AOS-dev, I suspect this is due to email enumeration protection being enabled on your project. Can you try disabling it to see if you do get the correct error messages? You can disable it by following https://cloud.google.com/identity-platform/docs/admin/email-enumeration-protection#disable

danagbemava-nc avatar Nov 15 '23 11:11 danagbemava-nc

Hi @danagbemava-nc, many thanks for the response. I can confirm that indeed email enumeration protection is the source of this issue!

When I disable the email enumeration protection (per the instructions), the SignInScreen returns the expected error messages in the UI. FYI the setting which this came back for this in GCP console was simply:

  "emailPrivacyConfig": {}

When I subsequently re-enabled the email enumeration protection in GCP console (and without any changes, or even reloads in my app) the UI error re-appeared. FYI the relevant returned setting in this case was:

  "emailPrivacyConfig": {
    "enableImprovedEmailPrivacy": true
  }

While disabling email enumeration protection removes the issue, I hope we can agree it should not be a long-term workaround given a) it's now enabled by default (since Sept 15th, 2023) and b) Google recommends having it enabled. Coincidentally, I also mentioned this email enumeration issue in my NOTE: above in relation to the existing, expected error messages:

NOTE: Having separate error messages for invalid / non-existent account and wrong password is, in my view, not a good security practice as it allows people to discover valid accounts and greatly simplifies hacking of passwords.

It would be great if the resolution to this issue could also fix this and align the error messages for consistency across the platform. Thanks for the support !

Arik-AOS-dev avatar Nov 15 '23 12:11 Arik-AOS-dev

Hi @Arik-AOS-dev, thanks for confirming.

So the error message is not from the firebase_ui_auth but from the underlying firebase_auth plugin.

Transferring this to the flutterfire repo.

danagbemava-nc avatar Nov 16 '23 11:11 danagbemava-nc

Reproducible using the plugin auth example and a firebase project that has email enumeration protection enabled.

Triage report

To reproduce:

  • Use the plugin example with a firebase project that has email enumeration protection enabled
  • Test on iOS
  • Attempt to sign in with either an invalid email and password or a valid email but invalid password

You will see the raw message instead of properly formatted message.

cc @russellwheatley

danagbemava-nc avatar Nov 16 '23 11:11 danagbemava-nc

@Arik-AOS-dev Thanks for the report. I've checked and we actually don't get any nicely formatted messages from the iOS native SDK. Probably worth following up in the iOS repository.

Lyokone avatar Nov 22 '23 08:11 Lyokone

@Lyokone, I'm experiencing this issue as well in my personal project, where I get firebase_auth/internal-error instead of the expected invalid-login-credentials when calling signInWithEmailAndPassword with invalid email or password. I would be happy to file an issue to get this resolved if you tell me which iOS repository you are referring to. I would also appreciate more details on what is needed from the iOS repo for the firebase_auth package to properly return invalid-login-credentials when entering an invalid email or password.

Peetee06 avatar Jan 08 '24 17:01 Peetee06

I've just tested this on in the auth example app across web, android and iOS. I got the same error:

[firebase_auth/invalid-credential] The supplied auth credential is incorrect, malformed or has expired.

Note; project needs email enumeration protection enabled to see it. If you see this issue on flutter-ui you should open the issue on that repo: https://github.com/firebase/FirebaseUI-Flutter

It is not an issue on FlutterFire.

russellwheatley avatar Feb 23 '24 11:02 russellwheatley