firebase / firebase-ios-sdk

Firebase SDK for Apple App Development
https://firebase.google.com
Apache License 2.0
5.64k stars 1.48k forks source link

AppCheck doesn't generate new key on error #11926

Closed jostster closed 11 months ago

jostster commented 1 year ago

Description

We have noticed instances where a valid app check token isn't generated. One such instance was when an employee got a new phone and ported his existing phone to his new one (iPhones).

When trying to authenticate with our app which uses firebase auth, he now gets Firebase App Check token is invalid. It appears that there isn't logic in the firebase app check module to regenerate a key / token when this happens. Only logic for when the error contains MISSING_RECAPTCHA_TOKEN.

This error is possibly caused by an identifier that was assigned by the old device which now differs on the new device. Logic should be added to refresh this if the error happens.

Domain=FIRAuthErrorDomain Code=17999 "An internal error has occurred, print and inspect the error details for more information." UserInfo={FIRAuthErrorUserInfoNameKey=ERROR_INTERNAL_ERROR, NSLocalizedDescription=An internal error has occurred, print and inspect the error details for more information., NSUnderlyingError=0x280072a00 {Error Domain=FIRAuthInternalErrorDomain Code=3 "(null)" UserInfo={NSUnderlyingError=0x280071a70 {Error Domain=com.google.HTTPStatus Code=401 "(null)" UserInfo={data={length = 284, bytes = 0x7b0a2020 22657272 6f72223a 207b0a20 ... 220a2020 7d0a7d0a }, data_content_type=application/json; charset=UTF-8}}, FIRAuthErrorUserInfoDeserializedResponseKey={
    code = 401;
    errors =     (
                {
            domain = global;
            message = "Firebase App Check token is invalid.";
            reason = unauthorized;
        }
    );
    message = "Firebase App Check token is invalid.";
    status = UNAUTHENTICATED;
}}}}

Reproducing the issue

  1. Login to an application that uses Firebase Auth and App Check.
  2. Migrate to a new iPhone and have it transfer all your apps from your existing phone to your new phone.
  3. Open the application on your new phone and logout. (Notice you will be logged in after the migration)
  4. Attempt to login on the new phone and you will receive the above errors.

Firebase SDK Version

10.15.0

Xcode Version

15

Installation Method

Swift Package Manager

Firebase Product(s)

AB Testing, Analytics, App Check, App Distribution, Authentication, Crashlytics, DynamicLinks, Installations, Messaging, Performance, Remote Config

Targeted Platforms

iOS

Relevant Log Output

No response

If using Swift Package Manager, the project's Package.resolved

Expand Package.resolved snippet
```json { "pins" : [ { "identity" : "abseil-cpp-binary", "kind" : "remoteSourceControl", "location" : "https://github.com/google/abseil-cpp-binary.git", "state" : { "revision" : "bfc0b6f81adc06ce5121eb23f628473638d67c5c", "version" : "1.2022062300.0" } }, { "identity" : "alamofire", "kind" : "remoteSourceControl", "location" : "https://github.com/Alamofire/Alamofire.git", "state" : { "revision" : "bc268c28fb170f494de9e9927c371b8342979ece", "version" : "5.7.1" } }, { "identity" : "alamofireimage", "kind" : "remoteSourceControl", "location" : "https://github.com/Alamofire/AlamofireImage.git", "state" : { "revision" : "98cbb00ce0ec5fc8e52a5b50a6bfc08d3e5aee10", "version" : "4.2.0" } }, { "identity" : "amplitude-ios", "kind" : "remoteSourceControl", "location" : "https://github.com/amplitude/Amplitude-iOS", "state" : { "revision" : "94160a550835e6f0a1df9fa76ab3902ac4648a9c", "version" : "8.17.1" } }, { "identity" : "analytics-connector-ios", "kind" : "remoteSourceControl", "location" : "https://github.com/amplitude/analytics-connector-ios.git", "state" : { "revision" : "d2f3ec4b022211a67d5d4509135d84359f7f8b8d", "version" : "1.0.2" } }, { "identity" : "apollo-ios", "kind" : "remoteSourceControl", "location" : "https://github.com/apollographql/apollo-ios.git", "state" : { "revision" : "97ad4f5b41f003f4f283c5f3386fb773af17aa67", "version" : "1.3.2" } }, { "identity" : "appsflyerframework", "kind" : "remoteSourceControl", "location" : "https://github.com/AppsFlyerSDK/AppsFlyerFramework", "state" : { "revision" : "d798f38fdc006621f5720579fdcba292c522a660", "version" : "6.12.1" } }, { "identity" : "asn1swift", "kind" : "remoteSourceControl", "location" : "https://github.com/tikhop/ASN1Swift", "state" : { "revision" : "b53bee03a942623db25afc5bfb80227b2cb3b425", "version" : "1.2.4" } }, { "identity" : "braze-swift-sdk", "kind" : "remoteSourceControl", "location" : "https://github.com/braze-inc/braze-swift-sdk", "state" : { "revision" : "47b2755fc8914ba8f55aa796060283368fc0fc69", "version" : "6.6.1" } }, { "identity" : "chargebee-ios", "kind" : "remoteSourceControl", "location" : "https://github.com/tommyboytech/chargebee-ios", "state" : { "revision" : "1dabafec5ca1c1e901244eff27c44ca93aef088d" } }, { "identity" : "confettiswiftui", "kind" : "remoteSourceControl", "location" : "https://github.com/simibac/ConfettiSwiftUI.git", "state" : { "revision" : "8d3a15d0aa2991e0761749b767ef8d89bca6275a", "version" : "1.0.1" } }, { "identity" : "experiment-ios-client", "kind" : "remoteSourceControl", "location" : "https://github.com/amplitude/experiment-ios-client", "state" : { "revision" : "e2909462c1f4be3df5b3d27ca535f6500ef5f101", "version" : "1.11.0" } }, { "identity" : "facebook-ios-sdk", "kind" : "remoteSourceControl", "location" : "https://github.com/facebook/facebook-ios-sdk", "state" : { "revision" : "c19607d535864533523d1f437c84035e5fb101cf", "version" : "14.1.0" } }, { "identity" : "factory", "kind" : "remoteSourceControl", "location" : "https://github.com/hmlongco/Factory", "state" : { "revision" : "39ff6a675cd0272d833d184d35add0f8fddd63de", "version" : "1.3.7" } }, { "identity" : "firebase-ios-sdk", "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/firebase-ios-sdk.git", "state" : { "revision" : "a580250a9ff49ec38da5430cef20f88ddc831db2", "version" : "10.12.0" } }, { "identity" : "googleappmeasurement", "kind" : "remoteSourceControl", "location" : "https://github.com/google/GoogleAppMeasurement.git", "state" : { "revision" : "0a226a8c50494c4cb877fbde27ab6374520a3354", "version" : "10.12.0" } }, { "identity" : "googledatatransport", "kind" : "remoteSourceControl", "location" : "https://github.com/google/GoogleDataTransport.git", "state" : { "revision" : "98a00258d4518b7521253a70b7f70bb76d2120fe", "version" : "9.2.4" } }, { "identity" : "googleutilities", "kind" : "remoteSourceControl", "location" : "https://github.com/google/GoogleUtilities.git", "state" : { "revision" : "4446686bc3714d49ce043d0f68318f42ed718cb6", "version" : "7.11.4" } }, { "identity" : "grpc-binary", "kind" : "remoteSourceControl", "location" : "https://github.com/google/grpc-binary.git", "state" : { "revision" : "f1b366129d1125be7db83247e003fc333104b569", "version" : "1.50.2" } }, { "identity" : "gtm-session-fetcher", "kind" : "remoteSourceControl", "location" : "https://github.com/google/gtm-session-fetcher.git", "state" : { "revision" : "d415594121c9e8a4f9d79cecee0965cf35e74dbd", "version" : "3.1.1" } }, { "identity" : "inflectorkit", "kind" : "remoteSourceControl", "location" : "https://github.com/mattt/InflectorKit", "state" : { "revision" : "d8cbcc04972690aaa5fc760a2b9ddb3e9f0decd7", "version" : "1.0.0" } }, { "identity" : "ios-analytics-debugger-spm", "kind" : "remoteSourceControl", "location" : "https://github.com/avohq/ios-analytics-debugger-spm", "state" : { "revision" : "b866a2ac3bb7540d17478e8cdca55fbef94abaf8", "version" : "1.3.0" } }, { "identity" : "leveldb", "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/leveldb.git", "state" : { "revision" : "0706abcc6b0bd9cedfbb015ba840e4a780b5159b", "version" : "1.22.2" } }, { "identity" : "lottie-spm", "kind" : "remoteSourceControl", "location" : "https://github.com/airbnb/lottie-spm.git", "state" : { "revision" : "60ea4f82fba8b4cb21a75665a889e86ed4d81c6e", "version" : "4.2.0" } }, { "identity" : "markdownkit", "kind" : "remoteSourceControl", "location" : "https://github.com/bmoliveira/MarkdownKit.git", "state" : { "revision" : "5056f3305d3499f44d8815530d560b87082e0cf5", "version" : "1.7.1" } }, { "identity" : "nanopb", "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/nanopb.git", "state" : { "revision" : "819d0a2173aff699fb8c364b6fb906f7cdb1a692", "version" : "2.30909.0" } }, { "identity" : "phonenumberkit", "kind" : "remoteSourceControl", "location" : "https://github.com/marmelroy/PhoneNumberKit.git", "state" : { "revision" : "9bc965a326df8d5115f0b7bb77f09c542b8ec417", "version" : "3.6.6" } }, { "identity" : "promises", "kind" : "remoteSourceControl", "location" : "https://github.com/google/promises.git", "state" : { "revision" : "e70e889c0196c76d22759eb50d6a0270ca9f1d9e", "version" : "2.3.1" } }, { "identity" : "pulse", "kind" : "remoteSourceControl", "location" : "https://github.com/kean/Pulse", "state" : { "revision" : "e8bc65bd43d1f32aef533e723f2d324830431120", "version" : "3.7.3" } }, { "identity" : "pulseloghandler", "kind" : "remoteSourceControl", "location" : "https://github.com/kean/PulseLogHandler.git", "state" : { "revision" : "3ca42eada318ad8ed9c3246f5e32c19413dae3ce", "version" : "3.2.0" } }, { "identity" : "sdwebimage", "kind" : "remoteSourceControl", "location" : "https://github.com/SDWebImage/SDWebImage.git", "state" : { "revision" : "936f1c7067728d16c362ba4fb93c17df78b5fd79", "version" : "5.18.2" } }, { "identity" : "sqlite.swift", "kind" : "remoteSourceControl", "location" : "https://github.com/stephencelis/SQLite.swift.git", "state" : { "revision" : "7a2e3cd27de56f6d396e84f63beefd0267b55ccb", "version" : "0.14.1" } }, { "identity" : "stripe-ios", "kind" : "remoteSourceControl", "location" : "https://github.com/stripe/stripe-ios", "state" : { "revision" : "e242f59ce90914e93c8308e0c3ceba7368575b77", "version" : "22.8.4" } }, { "identity" : "swift-argument-parser", "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-argument-parser.git", "state" : { "revision" : "fee6933f37fde9a5e12a1e4aeaa93fe60116ff2a", "version" : "1.2.2" } }, { "identity" : "swift-collections", "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-collections", "state" : { "revision" : "937e904258d22af6e447a0b72c0bc67583ef64a2", "version" : "1.0.4" } }, { "identity" : "swift-log", "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-log.git", "state" : { "revision" : "32e8d724467f8fe623624570367e3d50c5638e46", "version" : "1.5.2" } }, { "identity" : "swift-protobuf", "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-protobuf.git", "state" : { "revision" : "f25867a208f459d3c5a06935dceb9083b11cd539", "version" : "1.22.0" } }, { "identity" : "swiftygif", "kind" : "remoteSourceControl", "location" : "https://github.com/kirualex/SwiftyGif.git", "state" : { "revision" : "d6d26061d6553a493781ad3df4a8e275c43fc373", "version" : "5.4.4" } }, { "identity" : "tpinappreceipt", "kind" : "remoteSourceControl", "location" : "https://github.com/tikhop/TPInAppReceipt.git", "state" : { "revision" : "5b830d6ce6c34bb4bb976917576ab560e7945037", "version" : "3.3.4" } }, { "identity" : "youtube-ios-player-helper", "kind" : "remoteSourceControl", "location" : "https://github.com/youtube/youtube-ios-player-helper.git", "state" : { "revision" : "f57129cd4380ec0a74dd3a59da3270a1d653d59b", "version" : "1.0.4" } } ], "version" : 2 } ```

If using CocoaPods, the project's Podfile.lock

Expand Podfile.lock snippet
```yml Replace this line with the contents of your Podfile.lock! ```
google-oss-bot commented 1 year ago

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

jostster commented 1 year ago

According to https://developer.apple.com/documentation/devicecheck/establishing_your_app_s_integrity it looks like this is expected and a new key needs to be generated. However, I'm not finding where in the firebase-ios-sdk to generate a new key, only a new token.

jostster commented 1 year ago

To get around this issue I had to create an objective-c class that runs a performSelector on the private resetAttestation method.

- (FBLPromise<NSNull *> *)resetAttestation {
    FIRAppAttestProvider* provider = [[FIRAppAttestProvider alloc] initWithApp:[FIRApp defaultApp]];
    return [provider performSelector:@selector(resetAttestation)];
}

While this isn't elegant because it requires the user to attempt to login again, the true fix would be login in the Firebase AppAttest Provider to reset, regenerate then attempt login again.

umairalitail commented 1 year ago

Guys, any resolution for this? our users are probably facing the same issue. Some users changed to new iPhone 15. And this is probably the issue that is causing them not to receive the notifications as our back-end has not received any new token from those users. I would like to help as well if any.

jostster commented 1 year ago

@umairalitail this was being discussed in the draft PR. As a temp work around you can use my code above and include the obj-c class in your app so that you don't have to fork the firebase repo. What we do is check the signInWithPassword response and if it is a 17999 (internal error) we reset the key. A more in depth approach would be to check the associated errors for specific unauthorized errors with the 17999 but this should work fine for now.

umairalitail commented 1 year ago

@jostster I would try that. Thanks buddy!

andrewheard commented 12 months ago

@jostster @umairalitail We added a fix for resetting the attestation in Firebase https://github.com/firebase/firebase-ios-sdk/releases/tag/10.17.0. When you get a chance to upgrade, please let us know if 10.17.0 resolves the issue without your workaround.

google-oss-bot commented 11 months ago

Hey @jostster. We need more information to resolve this issue but there hasn't been an update in 5 weekdays. I'm marking the issue as stale and if there are no new updates in the next 5 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

google-oss-bot commented 11 months ago

Since there haven't been any recent updates here, I am going to close this issue.

@jostster if you're still experiencing this problem and want to continue the discussion just leave a comment here and we are happy to re-open this.