MaikuB / flutter_appauth

A Flutter wrapper for AppAuth iOS and Android SDKs
270 stars 243 forks source link

Support for handling Universal Links in iOS with PKCE OAuth flow? #293

Closed shobhitpuri closed 1 year ago

shobhitpuri commented 2 years ago

Thanks for creating and maintaining the wrapper around the native SDKs.

Issue: When using Flutter to develop the apps, I've implemented universal links for iOS. The https link open the iOS app, when it's clicked from outside the app, so they are set up properly. However, when the same URL is received as a callback URL as part of PKCE OAuth flow, there is no AuthorizationResponse received, when appAuth.authorize() is called, and the web view instance opened within the app doesn't close as well. This is with iOS 15.2, iPhone 13.

  const _config = AuthorizationServiceConfiguration(
    authorizationEndpoint: '.../authorize',
    tokenEndpoint: '.../token',
  );

  try {
    final result = await _appAuth.authorize(
      AuthorizationRequest(
        clientId,
        callbackURI,
        serviceConfiguration: _config,
        preferEphemeralSession: true
      ),
    );

When implementing PKCE OAuth flow with this library, an instance of ASWebAuthenticationSession seems to open within the app (since it seems the iOS library uses it for iOS 12+ and SFSafariViewController for pre iOS 12). After the user logs in successfully, the https link callback comes with an authorization_code as a 302 redirect. However, instead of closing the webview, and redirecting the flow back to the app, the URL is redirected within the webview. The weird part is that the same URL works when clicked outside the app. Has anyone experience this? And how did you fix it?

MaikuB commented 2 years ago

FYI this isn't something I've experienced doing so if you're running across the issue, you'd likely have better luck asking elsewhere or see if you can submit a fix for yourself. Potentially could be a known issue with the iOS SDK too

bigDado commented 2 years ago

This sounds a lot like the issue I'm facing... can someone with IOS experience fix this shit so we can move on :D

MathiasCochet commented 2 years ago

@shobhitpuri Did you end up finding a solution? I'm facing the same problem

shobhitpuri commented 2 years ago

@MathiasCochet We ended up using custom schema instead of universal link for callback. It is safe to do so for iOS 12+, since the library uses ASWebAuthenticationSession released by Apple specially for authentication use case. If you read the documentation, it says:

ASWebAuthenticationSession ensures that only the calling app’s session receives the authentication callback, even when more than one app registers the same callback URL scheme.

So we need not worry about other malicious apps handling the callback.

MaikuB commented 1 year ago

Closing as OP has switched custom scheme and there's been no one from the community who has come forward to submit a PR should there actually be an issue with the plugin

3asm commented 3 months ago

@shobhitpuri

The fact you are using ASWebAuthenticationSession for authentication callback is great, it does address the issue you mentioned, however, there are other issues where using a custom URL scheme (vs. universal link) remains an issue.

The first one is that the moment a scheme is used, it will be trusted by the OAuth IDP endpoint in the redirect_url. Attackers can therefore still trigger an authentication flow on the Android environment and hijack the response leading to an account takeover.

On iOS, while ASWebAuthenticationSession ensures the callback is sent to the calling app, it is still possible for a malicious app to trigger the authentication flow on its own declaring the same URL scheme that can't be advertised by any app and receive the authentication token. Most OAuth IDPs support an express flow that doesn't require user interaction making the issue more severe.

Both these issues can be addressed using verifiable universal links as they cannot be hijacked by an application on both Android and iOS.